完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
PCB板打样回来发现串口1 TXD 和RXD 与CH340的TXD RXD没有交叉相连,导致串口1无法使用,于是将错就错,采用模拟串口的方式弥补了这个错误。波特率可达115200,支持printf函数。
#include "sys.h" #include "delay.h" #include "led.h" #include "stdio.h" #define TX_L() GPIO_ResetBits(GPIOA, GPIO_Pin_10) #define TX_H() GPIO_SetBits(GPIOA, GPIO_Pin_10) #define RX_READ() (GPIOA->IDR & GPIO_Pin_9) u8 recvData=0;//!<接收的一个字节数据,全局变量 u32 delayTime = 8; //1000000/115200=8.6us /*! * @brief 模拟串口1 TX IO口配置 * @param none * @return none * @note Tx(PA10) */ void MUSART1_TX_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_10);//TXD 空闲状态是高电平 } /*! * @brief 模拟串口1 RX IO口配置 * @param none * @return none * @note Rx(PA9) */ void MUSART1_RX_init(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//!<外部中断时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource9); EXTI_InitStructure.EXTI_Line=EXTI_Line9; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿中断 EXTI_InitStructure.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x2; //抢占优先级 2, NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); } /*! * @brief 定时器14初始化 * @param 定时器14复位后时钟=168M/2=84M * @return NONE * @note 8us定时器,用于串口数据采样 */ void Time14Init(void) { TIM_TimeBaseInitTypeDef TIM_TimerBaseStruct; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);//!<时钟使能 TIM_DeInit(TIM14); //! TIM_TimerBaseStruct.TIM_Period=8;//!<设置重载寄存器初值 (设置为7,即:定时8us) TIM_TimerBaseStruct.TIM_Prescaler=83; //!<使用42M时钟,T=(83+1)*(7+1) /84= 8us TIM_TimerBaseStruct.TIM_ClockDivision=0; //!<不分频 TIM_TimerBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; //!<设置计数器向上计数模式 TIM_TimeBaseInit(TIM14,&TIM_TimerBaseStruct); NVIC_InitStructure.NVIC_IRQChannel=TIM8_TRG_COM_TIM14_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//定时器优先级一定要最高 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update); TIM_ITConfig(TIM14,TIM_IT_Update,ENABLE); //!<使能TIM1中断源 TIM_Cmd(TIM14,DISABLE); //!<禁能TIM1定时器 } /*! * @brief 模拟串口1发送一个字节 * @param * @return none * @note 数据低位在前高位在后 */ void MUSART1_SendData(u8 data)//发送一个数据 { u8 i = 0; TX_L(); //!<起始位 delay_us(delayTime); for(i = 0; i < 8; i++) { if(data & 0x01) TX_H(); else TX_L(); delay_us(delayTime); data >>= 1; } TX_H(); //!<停止位 delay_us(delayTime); } u8 RevSucc=0;//接收完成标志位 u8 MUSART1_ReadData(void)//接收一个数据 { while(RevSucc==0){}; RevSucc=0; return recvData; } /*! * @brief 串口接收IO中断处理函数 * @param none * @return NONE * @note none */ void EXTI9_5_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line9) != RESET) { EXTI->IMR &= 0<<9;//关闭EXTI_Line9上的中断(如果要开启中断,则反操作即可) if(RX_READ() == 0x00) { recvData = 0; TIM_SetCounter(TIM14,0); TIM_Cmd(TIM14, ENABLE); //打开定时器,接收数据 } EXTI_ClearITPendingBit(EXTI_Line9); } } /*! * @brief 定时器14中断处理函数 * @param * @return NONE * @note */ u8 count=0; void TIM8_TRG_COM_TIM14_IRQHandler(void) { if(TIM_GetITStatus(TIM14, TIM_IT_Update) != RESET) { if(RX_READ()) { recvData |= (1 << count);//读RX电平 } count++; if(count==8)//数据读取完成 { TIM_Cmd(TIM14, DISABLE);//!<关闭定时器 count = 0; RevSucc=1;//接收完成 EXTI->IMR|=1<<9; //开启外部中断 准备下一次接收 } TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update); } } #ifndef SIMULATION_USART1_H #define SIMULATION_USART1_H void MUSART1_TX_init(void); void MUSART1_RX_init(void); void Time14Init(void); void MUSART1_SendData(u8 data); u8 MUSART1_ReadData(void); #endif /****************************************************************/ /*名称: fputc */ /*功能: 重定向Printf*/ /*输入: 无*/ /*输出: 无*/ /**/ /****************************************************************/ int fputc(int ch, FILE *f) { //while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 // USART1->DR = (u8) ch; MUSART1_SendData(ch); return ch; } |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:14 , Processed in 1.124585 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号