|
调试程序的时候对于没有仿真器的朋友来说,使用串口是一个很好的方法(个人觉得),而使用printf这个函数会更加方便。
看了下WinAVR的手册,然后自己改写了一下,已经能实现printf函数的功能了,自己了加入了缓冲区。
/******************************************************************************************************************/
#ifndef __AVR_CPU_H__
#define __AVR_CPU_H__
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"
#include "avr/pgmspace.h"
#ifndef F_AVR_CPU
#define F_AVR_CPU 11059200UL //使用的晶振频率
#endif
typedef signed char int8s;
typedef unsigned char int8u;
typedef signed short int16s;
typedef unsigned short int16u;
typedef signed long int32s;
typedef unsigned long int32u;
#define SET_BIT( VAL,BIT ) ( VAL |= _BV(BIT) )
#define CLR_BIT( VAL,BIT ) ( VAL &= ~_BV(BIT) )
#ifndef NOP
#define NOP __asm("nop\n")
#endif
#endif
/********************************************************************************************************************/
#ifndef __USART_H__
#define __USART_H__
#include "avr_cpu.h"
#include <stdio.h>
extern void Printf_Init( void );
#endif
/********************************************************************************************************************/
#include "usart.h"
#define USART0_BAUDRATE 9600UL //波特率
#define USART0_TX0_BUFFER_SIZE 64 //缓冲区大小
static int uart_putchar( char c, FILE *stream ); //使用printf需要的
static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, //使用printf需要的
_FDEV_SETUP_WRITE );
static void Usart0_Init( void ); //串口0初始化
static void Usart0_Buffer_Init( void ); //串口0发送缓冲区初始化
volatile static unsigned char usart0_tx0_buffer[USART0_TX0_BUFFER_SIZE]; //定义缓冲区
volatile static unsigned char usart0_tx0_cnt; //有效数据的个数
volatile static unsigned char usart0_tx0_header; //头
volatile static unsigned char usart0_tx0_trail; //尾
//初始化printf
void Printf_Init( void )
{
Usart0_Buffer_Init( );
Usart0_Init( );
stdout = &mystdout;
}
//使用printf需要的,这里把要发送的数据放入发送缓冲区并发送出去
int uart_putchar( char c, FILE *stream )
{
if ( c == '\n' )
{
uart_putchar( '\r', stream );
}
while( usart0_tx0_cnt == USART0_TX0_BUFFER_SIZE )
{
//如果缓冲区溢出,则在这里等待
}
usart0_tx0_buffer[usart0_tx0_header] = c;
usart0_tx0_header++;
if ( usart0_tx0_header >= USART0_TX0_BUFFER_SIZE )
{
usart0_tx0_header = 0;
}
cli();
if ( usart0_tx0_cnt == 0 )
{
UDR0 = usart0_tx0_buffer[usart0_tx0_trail];
}
usart0_tx0_cnt++;
sei();
return 0;
}
//串口0初始化,发送暂时不接收,8位数据,1个停止位,9600波特率
static void Usart0_Init( void )
{
UCSR0A = 0x00;
UCSR0B = ( 1<<TXCIE )|( 1<<TXEN );
UCSR0C = ( 1<<UCSZ1 )|( 1<<UCSZ0 );
UBRR0H = (int8u)(F_AVR_CPU/(16*USART0_BAUDRATE)-1)/256;
UBRR0L = (int8u)(F_AVR_CPU/(16*USART0_BAUDRATE)-1)%256;
}
//初始化缓冲区数据
static void Usart0_Buffer_Init( void )
{
int8u i;
for ( i = 0; i < USART0_TX0_BUFFER_SIZE; i++ )
{
usart0_tx0_buffer = 0;
}
usart0_tx0_cnt = 0;
usart0_tx0_header = 0;
usart0_tx0_trail = 0;
}
//串口0发送中断服务程序
ISR( USART0_TX_vect )
{
if ( --usart0_tx0_cnt )
{
usart0_tx0_trail++;
if ( usart0_tx0_trail >= USART0_TX0_BUFFER_SIZE )
{
usart0_tx0_trail = 0;
}
UDR0 = usart0_tx0_buffer[usart0_tx0_trail];
}
else
{
usart0_tx0_trail = usart0_tx0_header;
}
}
在主程序中
int temp=1234;
printf( "The test value is %d", temp );
(原文件名:usart.jpg) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|