在线时间104 小时
UID3338547
注册时间2017-1-28
NXP金币14
TA的每日心情 | 无聊 2021-12-29 19:06 |
---|
签到天数: 47 天 连续签到: 1 天 [LV.5]常住居民I
金牌会员
 
- 积分
- 1392
- 最后登录
- 2025-3-4
|
本帖最后由 day_day 于 2019-2-26 11:29 编辑
(一)
这个板子做RS232,实际上说到底就是一个UART而已,RS232是硬件已经实现好TTL转RS232了,不需要软件端操心。
(二)接口定义
(三)端口初始化
首先设置复用:
都是第二个映射
- void UartGPIOInit(void)
- {
- //LPC_PINCON->PINSEL0 |= 0x00000050;
- PIN_Configure(0, 2, PIN_FUNC_1, PIN_PINMODE_PULLUP, PIN_PINMODE_PULLUP);
- PIN_Configure(0, 3, PIN_FUNC_1, PIN_PINMODE_PULLUP, PIN_PINMODE_PULLUP);
- }
复制代码
我是用PIN_Configure设置,一开始打算直接操作寄存器,但想了想还是不怎么明了
(四)UART设置
UART相关寄存器:
主要是波特率设置的两个寄存器:DLL、DLM
此外还有一个配置寄存器,用于配置奇偶校核位之类的东西,还有锁住波特率设置的两个寄存器的标志位:LCR
波特率设置实际上困扰了我一阵子
- uint16_t usFdiv = ((SystemCoreClock/4)/16)/bps;
复制代码
SystemCoreClock/4是uart0总线时钟,在时钟树上面有相关的位配置。
但为何要/16让我有些疑惑,后来才发现发送一个字节需要16个位,前8个是一个字节里面的八个位,后面是一些奇偶校核之类的,详见:
串口、波特率等概念
- LPC_UART0->LCR = 0x83; //使能访问除数锁存器,8 bits, no Parity, 1 Stop bit */
- LPC_UART0->DLM = usFdiv / 256; //初始化波特率 */
- LPC_UART0->DLL = usFdiv % 256;
- LPC_UART0->LCR = 0x03; //禁止访问除数锁存器,锁定波特率
-
复制代码
这样就基本可以正常通讯了,使用函数:
- int sendchar (int ch) { /* Write character to Serial Port */
- while (!(LPC_UART0->LSR & 0x20));
- return (LPC_UART0->THR = ch);
- }
复制代码
(四)重定向
加入头文件stdio.h
- #pragma import(__use_no_semihosting)
- //标准库需要的支持函数
- struct __FILE { int handle; }; /* Add whatever you need here */
- FILE __stdout;
- FILE __stdout;
- //定义_sys_exit()以避免使用半主机模式
- void _sys_exit(int return_code) {
- label: goto label; /* endless loop */
- }
- //重定义fputc函数
- int fputc(int ch, FILE *f) {
- return (sendchar(ch));
- }
复制代码
(五)UART设置
以上是非常基本的UART配置,只能用于基本的阻塞通讯,要想启动中断,还需要配置IER寄存器和使能NVIC
- LPC_UART0->FCR = 0x00; //禁止FIFO
- NVIC_ClearPendingIRQ(UART0_IRQn);
- NVIC_SetPriority(UART0_IRQn, 0);
- NVIC_EnableIRQ(UART0_IRQn); /* enable irq in nvic */
- LPC_UART0->IER = 0x01; //使能接收中断
复制代码
中断相关配置:
- void UartInit(uint32_t bps)
- {
- uint16_t usFdiv = ((SystemCoreClock/4)/16)/bps;
-
- UartGPIOInit();
- // LPC_UART0->RBR; //缓冲接收寄存器
- // LPC_UART0->THR; //发送寄存器
- // LPC_UART0->DLL; //波特率低位
- // LPC_UART0->DLM; //波特率高位
-
- LPC_UART0->LCR = 0x83; //使能访问除数锁存器,8 bits, no Parity, 1 Stop bit */
- LPC_UART0->DLM = usFdiv / 256; //初始化波特率 */
- LPC_UART0->DLL = usFdiv % 256;
- LPC_UART0->LCR = 0x03; //禁止访问除数锁存器,锁定波特率
-
- LPC_UART0->FCR = 0x00; //禁止FIFO
- NVIC_ClearPendingIRQ(UART0_IRQn);
- // NVIC_SetPriority(UART0_IRQn,NVIC_EncodePriority(SYS_NVIC_GROUP,UART0_PreemptPriority,UART0_SubPriority));
- NVIC_SetPriority(UART0_IRQn, 0);
- NVIC_EnableIRQ(UART0_IRQn); /* enable irq in nvic */
- LPC_UART0->IER = 0x01; //使能接收中断
- }
- char RxBuf[50]="";
- struct _usart_flag usart0_flag={0,0,0};
- void UartRxInBuf(uint8_t str)
- {
- if(usart0_flag.rec_end_flag==0)//接收未完成
- {
- if(usart0_flag.rec_middle_flag)//接收到了0x0d
- {
- if(str!=0x0a)
- usart0_flag.rec_middle_flag = 0;//接收错误,重新开始
- else
- usart0_flag.rec_end_flag = 1; //接收完成了
- }
- else //还没收到0X0D
- {
- if(str==0x0d)
- usart0_flag.rec_middle_flag = 1;
- else
- {
- RxBuf[usart0_flag.size]=str ;
- usart0_flag.size++;
- if(usart0_flag.size>(50-1))
- memset(&usart0_flag, 0, sizeof(usart0_flag)); //接收数据错误,重新开始接收
- }
- }
- }
- }
- #define UART_IIR_RLS 3
- #define UART_IIR_CTI 6
- #define UART_IIR_RDA 2
- #define UART_LSR_RDR 0x01
- #define UART_LSR_OE 0x02
- #define UART_LSR_PE 0x04
- #define UART_LSR_FE 0x08
- #define UART_LSR_THRE 0x20
- #define UART_LSR_TEMT 0x40
- #define UART_LSR_RXFE 0x80
- void UART0_IRQHandler(void)
- {
- uint8_t IIRValue;
- uint8_t LSRValue;
- uint8_t Dummy = 0;
- // Uart_Buf *p = NULL;
- bool bFlag = true;
- while ( bFlag ) { // 等待产生的所有中断处理完?
- IIRValue = LPC_UART0->IIR; // 读取中断状态寄存器
- IIRValue >>= 1; // 屏蔽IIR中不需要的信息
- IIRValue &= 0x07; // 效验1~3BIT 对中断状态识别
- switch (IIRValue) { //
- case UART_IIR_RLS : // --接收线状态
- LSRValue = LPC_UART0->LSR; // 读取线状态信息
- Dummy = UART_LSR_OE | UART_LSR_PE | UART_LSR_FE | UART_LSR_RXFE;
- if ( LSRValue & Dummy) { // -- 线状态 接收有关中断 只丢弃错误的成对接收RSR中字符
- Dummy = LPC_UART0->RBR; // 读出成对字符 丢弃
- break; // 下一个中断标志处理
- }
- if ( LSRValue & UART_LSR_RDR ) { // -- 线状态 接收数据就绪
- Dummy = LPC_UART0->RBR; // 读数据 时会清除中断
- UartRxInBuf(Dummy); // 进缓存
- }
- if ( ( LSRValue & UART_LSR_THRE) || // -- 线状态 发送保持寄存器空
- ( LSRValue & UART_LSR_TEMT) ) { // -- 线状态 发送器空
- // p = &UartTx[0]; // 取对应串口发送缓存信息
- // if (p->Cnt > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据
- // LPC_UART0->THR = UartTxOutBuf(0); // 读走一个数据到发送寄存器
- // } else {
- // UartTxFlag[0] = FALSE; // 发送标志为0表示 可以直接发送信息
- // }
- }
- break;
- case UART_IIR_CTI : // -- 字符超时
- Dummy = LPC_UART0->RBR; // 读数据
- UartRxInBuf(Dummy); // 进接受缓存
- break;
- case UART_IIR_RDA : // -- 数据接收
- Dummy = LPC_UART0->RBR; // 读数据
- UartRxInBuf(Dummy); // 进接受缓存
- break;
- // case UART_IIR_THRE : // -- 发送空
- // p = &UartTx[0]; // 取对应串口发送缓存信息
- // if (p->Cnt > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据
- // LPC_UART0->THR = UartTxOutBuf(0); // 读走一个数据到发送寄存器
- // } else {
- // UartTxFlag[0] = FALSE; // 发送标志为0表示 可以直接发送信息
- // }
- // break;
- default : // -- 默认处理 空
- bFlag = false; // 没有中断需要处理了
- break;
- }
- }
- }
复制代码
|
|