ARM32开发——串口库封装(初级)

#include "USART0.h" #include <stdio.h> void USART0_init(void) { // GPIO 初始化 ---------------------------------------------------- // 启用GPIO时钟 rcu_periph_clock_enable(RCU_GPIOA); /* 配置TX PA9和RX PA10引脚 */ gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); /* configure the USART0 TX pin and USART0 RX pin */ gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9); gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10); // 串口 初始化 ---------------------------------------------------- // 启用USART0时钟 rcu_periph_clock_enable(RCU_USART0); // 重置(可选) usart_deinit(USART0); // 配置串口参数:波特率*, 数据位,校验位,停止位, 大小端模式 usart_baudrate_set(USART0, 115200UL); // 波特率:必填 usart_word_length_set(USART0, USART_WL_8BIT); // 数据位:默认8bit usart_parity_config(USART0, USART_PM_NONE); // 校验位:默认无校验 usart_stop_bit_set(USART0, USART_STB_1BIT); // 停止位:默认1bit usart_data_first_config(USART0, USART_MSBF_LSB);// 大小端模式:默认小端 // 启用发送功能 usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); // 启用接收功能 usart_receive_config(USART0, USART_RECEIVE_ENABLE); // 开启接收中断 nvic_irq_enable(USART0_IRQn, 2, 2); // 启用RBNE中断,读数据缓冲区不为空中断 usart_interrupt_enable(USART0, USART_INT_RBNE); // 启用IDLE中断,空闲中断 usart_interrupt_enable(USART0, USART_INT_IDLE); // 启用USART usart_enable(USART0); } // 发送1个byte数据 void USART0_send_byte(uint8_t byte){ // 从USART0的TX发送一个字节出去 usart_data_transmit(USART0, (uint8_t)byte); // 等待发送完成 (轮询等待发送数据缓冲区为空) while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)); } // 发送多个byte数据 void USART0_send_data(uint8_t* data, uint32_t len){ // 满足:1.data指针不为空 2.长度不为0 while(data && len--){ USART0_send_byte(*data); data++; } } // 发送字符串 (结尾标记\0) void USART0_send_string(char *data){ // 满足:1.data指针不为空 2. 数据不能是\0 while(data && *data){ USART0_send_byte((uint8_t)*data); data++; } } #if USART0_PRINTF // 配置printf打印函数 int fputc(int ch, FILE *f) { USART0_send_byte(ch); return ch; } #endif /************************************ 中断函数:收到标记信号,马上执行 1. 触发中断函数的原因(标记)有很多 2. 需要区分是哪个标记触发的中断 RBNE: read data buffer not empty 中断函数名不能随便写,要根据中断向量表复制 *************************************/ #define RX_BUFFER_LEN 1024 uint8_t g_rx_buffer[RX_BUFFER_LEN]; uint32_t g_rx_cnt = 0; void USART0_IRQHandler(void){ if(SET == usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){ // 收到数据 // printf(">RBNE<\n"); // 清理标记(避免多次触发中断) usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE); // 获取寄存器里的数据 uint8_t data = usart_data_receive(USART0); // 缓存到buffer中 g_rx_buffer[g_rx_cnt++] = data; // 避免缓冲区溢出 (可选) if(g_rx_cnt >= RX_BUFFER_LEN) g_rx_cnt = 0; // 原样返回 send_byte(data); } if(SET == usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)){ // printf(">IDLE<\n"); // 空闲 // 清理标记(无效) usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE); // 只能使用以下方式清理IDLE标记 usart_data_receive(USART0); // 必须读取一次USART0,读到的结果没有用 // 添加字符串结束标记,避免打印出错 g_rx_buffer[g_rx_cnt] = '\0'; #if USART0_RECV_CALLBACK // printf("%s", g_rx_buffer); USART0_on_recv(g_rx_buffer, g_rx_cnt); #endif // 把缓冲区[0, g_rx_cnt)设置为0x00 (可选) // memset(g_rx_buffer, 0x00, g_rx_cnt); // 重置缓冲区数据个数 g_rx_cnt = 0; } }
上一篇:python使用opencv实现火焰检测


下一篇:Docker基本架构概览-1