📄 uart.c
字号:
/////////////////////////////////////
//070410
//在发送函数中加上超时处理
//防止发送失败进入死循环
/////////////////////////////////////
#define _UART_C_
#define BAUD 9600
#define CRYSTAL 11059200
#define BAUD_SETTING (unsigned int)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1)
#define BAUD_H (unsigned char)(BAUD_SETTING>>8)
#define BAUD_L (unsigned char)(BAUD_SETTING)
#include <includes.h>
// 初始化串口
void uartInit(uint8 uartNum)
{
OS_ENTER_CRITICAL();
if(1==uartNum)
{
UCSR1B = 0x00; //disable while setting baud rate
UCSR1A = 0x00;
UCSR1C = 0x06;
UBRR1L = BAUD_L; //set baud rate lo
UBRR1H = BAUD_H; //set baud rate hi
UCSR1B = 0x98; // 接收、发送使能,接收中断使能
//共有3个中断源, 接受, 发送, 寄存器空, 对应此寄存器的高3位
inRxd1Buf = Rxd1Buf;
outRxd1Buf = Rxd1Buf;
}
else
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00;
UCSR0C = 0x06; //set frame format, 8 bits, 2stop]
UBRR0H = BAUD_H;
UBRR0L = BAUD_L;
UCSR0B = 0x98; //0x18为允许接收和发关,0x98时全能接收中断,允许接收.
inRxd0Buf = Rxd0Buf;
outRxd0Buf = Rxd0Buf;
}
OS_EXIT_CRITICAL();
}
// 发送1个字节的数据
uint8 putChar(uint8 num, uint8 dat)
{
if(1 == num)
{
while ( !( UCSR1A & (1<<UDRE1)) )
;
UDR1 = dat;
}
else if(0 == num)
{
while ( !( UCSR0A & (1<<UDRE0)) )
;
UDR0 = dat;
}
else
{
return 0;
}
return 1;
}
// 发送完整的字符串
uint8 putStr(uint8 num, uint8 *str, uint8 len)
{
uint8 i = 0;
//ENTER_CRITICAL();
while((*str != NULL) && (len > 0))
{
if(0 == putChar(num, *str) )
{
return i;
}
i++;
str++;
len--;
}
return i;
//EXIT_CRITICAL();
}
//发送一个字节的hex码,分成两个字节发。
uint8 const hex_[] = {"0123456789ABCDEF"};
uint8 putCharHex(uint8 num, uint8 dat)
{
uint8 ch;
uint8 flag;
ch = (dat >> 4) & 0x0F;
flag = putChar(num, hex_[ch]);
if (0 == flag)
{
return 0;
}
ch = dat & 0x0F;
flag = putChar(num, hex_[ch]);
if (0 == flag)
{
return 0;
}
return 1;
}
// 将字符串以HEX格式发送
uint8 putStrHex(uint8 num, uint8 *str, uint8 len)
{
uint8 i = 0;
while((*str != NULL) && (len > 0))
{
if (0 == putCharHex(num, *str))
{
return i;
}
str++;
i++;
len--;
}
return i;
}
// 从串口缓冲区中读取1个字节的数据
int16 getChar(uint8 num)
{
uint8 temp=0;
uint8 timeout = 10;
if(1==num)
{
while(timeout)
{
if(Rxd1BufCnt != 0)
{
temp = *outRxd1Buf;
if(outRxd1Buf == &Rxd1Buf[Rxd1BufLen - 1])
{
outRxd1Buf = Rxd1Buf; // 地址到顶部后回到底部
}
else
{
outRxd1Buf++; // 输出指针右移1位
}
Rxd1BufCnt--; // 缓冲区中数据个数减1
return (temp); // 读到数据,退出
}
else
{
timeout--; // 缓冲区中没有数据,计时减1
DelayMs(); // 缓冲区中没有数据,延时1ms
}
}
}
else if (0 == num)
{
while(timeout)
{
if(Rxd0BufCnt != 0)
{
temp = *outRxd0Buf;
if(outRxd0Buf == &Rxd0Buf[Rxd0BufLen - 1])
{
outRxd0Buf = Rxd0Buf; // 地址到顶部后回到底部
}
else
{
outRxd0Buf++; // 输出指针右移1位
}
Rxd0BufCnt--; // 缓冲区中数据个数减1
return (temp); // 读到数据,退出
}
else
{
timeout--; // 缓冲区中没有数据,计时减1
DelayMs(); // 缓冲区中没有数据,延时1ms
}
}
}
else
{
return (-1);
}
return (-1);
}
// 从串口缓冲区中读取n个字节的数据到dest中
uint8 getStrLong(uint8 num, uint8 len, uint8 *dest)
{
uint8 i = 0;
INT16S c = 0;
INT8U cnt = 0;
INT8U *pDest = dest;
for(i = 0; i < len; i++)
{
c = getChar(num);
if(c == -1)
{
return cnt;
//return pDest;
}
else
{
cnt++;
*dest++ = (INT8U)(c);
}
}
return cnt;
//return pDest;
}
// 从串口缓冲区中读取某符号前的所有数据< Rxd0BufLev2Len 到dest中
uint8 getStr(uint8 num, uint8 c, uint8 *dest)
{
uint8 i = 0;
uint16 ch;
while((uint8)(ch = getChar(num))!= c)
{
if(-1 == ch)
{
return i;
}
*dest++ = (uint8)ch;
}
return i;
}
////////////////////////////////////////////////
//UART1 接受完成中断
////////////////////////////////////////////////
#pragma interrupt_handler uart1_rx_isr:31
void uart1_rx_isr(void)
{
unsigned char temp;
//ENTER_CRITICAL();//uart has received a character in UDR
temp = UDR1;
if(Rxd1BufLen > Rxd1BufCnt)
{
*inRxd1Buf = temp;
Rxd1BufCnt++; // 缓冲区中数据计数器加1
if(inRxd1Buf == &Rxd1Buf[Rxd1BufLen -1])
{
inRxd1Buf = Rxd1Buf; // 地址到顶部后回到底部
}
else
{
inRxd1Buf++; // 指针右移1位
}
}
//putChar(0, temp);
//EXIT_CRITICAL();
}
////////////////////////////////////////////////
//UART0 接受完成中断
////////////////////////////////////////////////
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RX //iv_USART0_RXC
void uart0_rx_isr(void)
{
unsigned char data;
//ENTER_CRITICAL();//uart has received a character in UDR
data = UDR0;
if(Rxd0BufLen > Rxd0BufCnt)
{
*inRxd0Buf = data;
Rxd0BufCnt++; // 缓冲区中数据计数器加1
if(inRxd0Buf == &Rxd0Buf[Rxd0BufLen -1])
{
inRxd0Buf = Rxd0Buf; // 地址到顶部后回到底部
}
else
{
inRxd0Buf++; // 指针右移1位
}
}
//putChar(0, (INT8U)getChar(0));
//EXIT_CRITICAL();
}
///////////////////////////////////////////////
//发送寄存器空中断
///////////////////////////////////////////////
#pragma interrupt_handler uart1_udre_isr:32
void uart1_udre_isr(void)
{
//ENTER_CRITICAL();//character transferred to shift register so UDR is now empty
//EXIT_CRITICAL();
}
//////////////////////////////////////////////
//发送完成中断
//////////////////////////////////////////////
#pragma interrupt_handler uart1_tx_isr:33
void uart1_tx_isr(void)
{
//ENTER_CRITICAL();;//character has been transmitted
//EXIT_CRITICAL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -