📄 uart.c
字号:
{
uint16 i;
for(i=0; i<Size; i++,Ret++)
{
if((Uart0Getch((uint8 *)Ret, QUEUE_ACCEPT))!=SYS_ERR_OK)
{
return i;
}
}
return i;
}
/*********************************************************************************************************
** 函数名称: UART0Getch
** 功能描述: 接收一个字节
** 输 入: 无
** 输 出: SYS_ERR_OK:接收到的数据
** SYS_ERR_FAIL:没有接收到数据
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年7月4日
**-------------------------------------------------------------------------------------------------------
** 修改人: Zbj
** 日 期: 2007.11.27
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
sys_err Uart0Getch(uint8 *Ret, q_mod Mod)
{
if(QueueRead(Ret, (void *)Uart0RecvBuf,Mod)==QUEUE_OK)
{
return SYS_ERR_OK;
}
return SYS_ERR_FAIL;
}
int UartStart(void)
{
U32 sysclk = 70000000; //;系统时钟 20MHz, 30MHz, 40MHz, 50MHz, 60MHz
int recie = 1; //;接收中断使能 0 disable, 1 enble
int thrie = 0; //;发送中断使能 0 disable, 1 enble
/* open uart0 interrrupt mask */
//unmask_irq(INT_UART0);//;根据参数中断号判断出uart0屏蔽打开
Uart0Init(sysclk, uart_baudrate, uart_databit, uart_trigerlevel);//;初始化uart0
unmask_irq(INT_UART0);//根据参数中断号判断出uart0屏蔽打开
Uart0_Int_En(recie, thrie);
// *(RP)INTC_IEN = 0X01800000; //第23,24位置1,打开uart1 uart0
if (QueueCreate((void *)Uart0SendBuf,
UART0_SEND_QUEUE_LENGTH,
NULL,
(uint8 (*)())UartWriteFull)
== NOT_OK)
{
return FALSE;
}
//建立接收数据队列
if (QueueCreate((void *)Uart0RecvBuf,
UART0_RECV_QUEUE_LENGTH,
(uint8 (*)())UartReadEmpty,
NULL)
== NOT_OK)
{
return FALSE;
}
return 0;
}
int Uart0Init(U32 sysclk, U32 baudrate, U32 databit, U32 trigerlevel)
{
U32 baud, bit, triger, baudh, baudl;
baud = sysclk/16/baudrate;//?
baudh = baud >> 8;//;波特率高8位赋值
baudl = baud & 0xff;//;波特率低8位赋值
switch(databit)//;根据数据位大小判断,
//;四种情况对应不同的数据比特数:00(5bits),01(6bits),10(7bits),11(8bits)
{
case 5: bit = 0x80;
break;
case 6: bit = 0x81;
break;
case 7: bit = 0x82;
break;
case 8: bit = 0x83;
break;
default: ;
break;
}
write_reg(UART0_LCR, bit); //divisor latch被访问,通过输入的数据bit第8位为1配置
write_reg(UART0_DLH, baudh);//将计算后的波特率写入高8位
write_reg(UART0_DLL, baudl);//将计算后的波特率写入低8位
read_reg(UART0_LCR) &= (~(0x1 << 7)); //通过UART0_LCR第7位和0相与置0,关闭波特率访问,
//转到普通寄存器的访问,至此完成的数据的初始化
switch(trigerlevel)//触发级初始化,定义transmitter FIFO的trigger level:00(0byte),
//01(2byte),10(4byte),11(8byte)
{
case 1: triger = 0x0;
break;
case 4: triger = 0x1;
break;
case 8: triger = 0x2;
break;
case 14: triger = 0x3;
break;
}
triger = (triger << 6);
write_reg(UART0_FCR, triger);
//这个函数同样方法可以定义receiver FIFO的trigger level。
write_reg(UART0_IER, 0x00);//关闭Uart中断
//
return E_OK;
}
int Uart0_Int_En(int recie, int thrie)//判断uart0是否准备接收和发送数据,从而决定FIFO的使能控制
{
if(recie == 1)//uart0准备好接收数据
read_reg(UART0_IER) |= 0x1;//开接收FIFO触发级中断使能/*received data available interrupt enable*/
else
if(recie == 0)//uart0没准备接收数据
read_reg(UART0_IER) &= ~0x1;//关闭接收FIFO触发级中断使能/*interrupt disable*/
if(thrie == 1)//uart0准备发送数据
read_reg(UART0_IER) |= (0x02);//开发送FIFO触发级空中断使能 /*transmitter holding register empty interrupt enable*/
else
if(thrie == 0)//uart0没准备好发送数据
read_reg(UART0_IER) &= ~(0x02); //关闭发送FIFO触发级空中断使能/*transmitter holding register empty interrupt disable*/
return E_OK;
}
/*中断服务程序*/
void Uart0_Exception(void)
{
uint8 i,temp;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL();
switch(( read_reg(UART0_IIR) & 0XE ) >> 1 )//判断bit【3:1】中断源标号
{
case 2 : //receiver data available interrupt接收FIFO中的数据达到触发级中断
for(i=0; i<UART_FIFO_LENGTH; i++)
{
if((read_reg(UART0_LSR)&0x01)==0x00) //没有数据
{
break;
}
temp = read_reg(UART0_RBR);//读取接收FIFO里的数据
QueueWrite((void *)Uart0RecvBuf,temp);
}
break;
case 6 : //time out interrupt超时中断
for(i=0; i<UART_FIFO_LENGTH; i++)
{
if((read_reg(UART0_LSR)&0x01)==0x00) //没有数据
{
break;
}
temp = read_reg(UART0_RBR);//读取接收FIFO里的数据
QueueWrite((void *)Uart0RecvBuf,temp);
}
break;
case 1 : //transmit holding register empty interrupt 传输FIFO中断
for (i = 0; i < UART_FIFO_LENGTH; i++) /* 向发送FIFO填充数据 */
{
if (QueueRead(&temp, Uart0SendBuf,QUEUE_ACCEPT) == QUEUE_OK)
{
write_reg(UART0_THR,temp);
}
else if(QueueRead(&temp, Uart0RecvBuf,QUEUE_ACCEPT) == QUEUE_OK)
{
write_reg(UART0_THR,temp);
}
else
{
read_reg(UART0_IER) &= ~(0x02); /* 队列空,则禁止发送中断 */
}
}
break;
default :
break ;
}
OS_EXIT_CRITICAL();
}
ER prints(char *s)//把数据打印到上位机超级终端
{
int i;
// U32 mask;
while(*s != '\0')
{
{
*(RP)UART0_THR = *s++;//利用指针传输数据,这个是硬件管理的,我们只要把指针指向首数据地址,并且建立循环
}
for(i=0; i<5000 ; i++) ;
}
*(RP)UART0_THR = '\n';
return E_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -