LPC824串口+定时器(MRT)配置完成串口的收发数据
日期: 2019-01-05 分类: 跨站数据测试 222次阅读
1.使用开关矩阵将对应的IO口复用到串口上
我这里使用的是串口0,p0_4复用为Usart0的TX引脚,p0_0复用到Usart0的RX引脚,这颗NXP芯片内置了开关矩阵,所以在使用反面就相对比较方便了,可以将任意一个IO口复用成你需要的模式,但是使用的时候要注意的是一些特定的引脚,像下载调试用的SWDIO和SWCLK这两个引脚就已经被占用的
LPC824Lite这个开发板使用方便的地方就是板载了一个LPC11U35的芯片,因此在调试下载的时候就比较方便了,不需要另外接下载线,直接用DAP,即可以当电源线,下载调试线也可以当串口线 ,所以我这里也是直接用0和4两个引脚当串口使用(使用DAP下载程序的时候需要在Debug里面选中CMSIS-DAP Debugger)
最后查看SWM关于串口0的寄存器,是在SWM的寄存器0上,因此吧U0_TX_O赋值为4(即使用P0_4当串口0的TX),RX类似
最后附上代码
LPC_SYSCTL->SYSAHBCLKCTRL|=1<<7; //开启SWM时钟
LPC_SWM->PINASSIGN[0]&=~0xFFFF;
LPC_SWM->PINASSIGN[0]|=0x04;
LPC_SYSCTL->SYSAHBCLKCTRL&=~(1<<7); //关闭SWM时钟(使用完之后记得关闭,节省功耗)
2.配置串口寄存器
串口的时钟源都是来自一个U_PCLK的时钟,这个时钟是由主时钟经过两次分频得到的(这里的主时钟不是系统时钟,主时钟是60M,系统时钟是经过主时钟2分频得到的为30M) ,U_PCLK的时钟在SYSCON里面可以进行配置
U_PCLK=(((60000000/LPC_SYSCTL->UARTCLKDIV)*256)/(uint64_t) (256 + LPC_SYSCON->UARTFRGMULT))
UARTCLKDIV控制U_PCLK的整数分频UARTFRGMULT控制U_PCLK的小数分频
在LPC_USART0->CFG寄存器里配置串口的数据位停止位相关配置
LPC_SYSCTL->SYSAHBCLKCTRL|=1<<14; //开启USART0时钟
LPC_SYSCTL->PRESETCTRL&=~(0x1<<3); //开启复位USART0
LPC_SYSCTL->PRESETCTRL|=(0x1<<3); //关闭复位USART0
LPC_USART0->CFG|=1<<0; //配置串口寄存器
LPC_USART0->CFG|=1<<2;
LPC_SYSCTL->UARTCLKDIV=60000000/(9600*100); //配置串口的时钟输入U_PCLK
LPC_SYSCON->UARTFRGDIV=0xFF;
LPC_SYSCON->UARTFRGMULT=((60000000/LPC_SYSCTL->UARTCLKDIV)*256)/60000000/(9600*100);
DEBUG_UART->BRG=(((60000000/LPC_SYSCTL->UARTCLKDIV)*256)/(uint64_t) (256 +LPC_SYSCON->UARTFRGMULT))/(16*9600)-1;
3.经过前面两步已经实现了串口的发送数据,现在要开启串口的接受中断
LPC_USART0->INTENSET|=1<<0; //开启串口接受中断
NVIC->ISER[0]|=1<<3;
4.编写串口中断处理函数
/*
UsartRxBuff:接受串口数据的BUFF
UsartRxDataLen:标志接受数据的长度
用定时器来判断一帧数据时候接受完毕若定时器定时时间 到串口还没有接受到数据则表示串口接受完了一帧数据,因此每次进入串口中断的时候都要将定时器复位
*/
void UART0_IRQHandler(void)
{
UsartRxBuff[UsartRxDataLen]=LPC_USART0->RXDATA;
UsartRxDataLen++;
LPC_MRT_CH0->INTVAL=30000000/1; //设置分频(这两行是定时器的,后面会有讲到)
LPC_MRT_CH0->CTRL|=1<<0; //开启定时器
}
5.初始化定时器MRT
/*
我这里是将定时器初始化为1S产生一次中断,MRT里有四个定时器,可以单独配置成不同的分频系数和重装值
在CTRL寄存器里可以配置定时器的模式,我这里配置的时循环进入中断模式Repeat interrupt mode.使能定时器也是在CTRL里面配置
*/
/*
函数功能:定时器初始化
*/
void TimerInit(void)
{
LPC_SYSCON->SYSAHBCLKCTRL|=1<<10; //开启定时器时钟
LPC_SYSCON->PRESETCTRL&=~(1<<7); //复位MRT
LPC_SYSCON->PRESETCTRL|=1<<7;
NVIC->ISER[0]|=1<<10; //开启定时器中断
LPC_MRT_CH0->INTVAL=30000000/1; //设置分频
LPC_MRT_CH0->INTVAL|=0x80000000;
LPC_MRT_CH0->STAT|=1<<0; //清除中断标志位
LPC_MRT_CH0->CTRL|=1<<0; //开启定时器
}
6.编写定时器中断处理函数
/*
函数功能:定时器中断处理函数
*/
void MRT_IRQHandler(void)
{
uint32_t int_pend;
/* Get interrupt pending status for all timers */
int_pend = Chip_MRT_GetIntPending();
Chip_MRT_ClearIntPending(int_pend);
LPC_MRT_CH0->CTRL&=~(1<<0); //接受完一帧数据,关闭定时器
UsartRxFlag=1; //标志位值1,告诉main函数接受到数据
}
7.main函数里面做数据处理
if(UsartRxFlag==1)
{
UsartRxFlag=0;
UsartRxBuff[UsartRxDataLen]='\0';
UsartSendStr(LPC_USART0,UsartRxBuff);
UsartRxDataLen=0;
}
8.串口发送函数
我这里写的串口发送函数不够完善,是根据结束符判断字符串时候结束,所以传进来的字符串必须要有结束符,改善的话还可以加一个长度限制,或者其他
/*
函数功能:串口发送字符串
*/
void UsartSendStr(LPC_USART_T *pUART,uint8_t *str)
{
while(*str!='\0')
{
while((LPC_USART0->STAT&(1<<2))!=0)
{
LPC_USART0->TXDATA=*str;
str++;
}
}
}
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
下一篇: unity如何与服务器数据交互
精华推荐