历史上的今天
今天是:2025年03月09日(星期日)
2019年03月09日 | STM32F407Z 模拟串口(115200波特率)
2019-03-09 来源:eefocus
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; }
史海拾趣
|
如何自制 USB电子琴 YouTube中视频效果 市场上的USB电子琴,多为出口单,产品类型基本上分为两种: 一是假USB,它只是多了一个USB接口,用来取电,作为电池以外的第二电源而已;其喇叭和音调发生器芯片,导致了它的乐器种类偏少、音色效果较低; ...… 查看全部问答> |
|
我只要求点亮LED数码管,不需要读取键盘。。。 我写的程序一个都不亮,请指教。 下面是我写的: 以下为代码内容 #include #define uchar unsigned char; #define uint unsigned int; sbit HD_CS=P0^2; sbit HD_CLK=P0^1; sbit HD_DATA=P0^0; vo ...… 查看全部问答> |
|
前一篇讲了串口发送,这一篇把串口接收补上。原本小鱼有水同学想这么做的,串口接收到什么就发送什么,无奈,小鱼有水写的发送模块和接收模块没对上号,导致上位机接收的字节数和发送的字节数不等,很郁闷,正应了那句话:时序是事先设计出来的,不 ...… 查看全部问答> |
|
多亏了Googleman的帮忙,现在已经解决多个图像的问题了,这里对他表示感谢。 我用的是2450, ov9650的摄像头。 现在我想把采集到的RGB图像转化成PC能识别的图像格式如jpeg,bmp。 现在没有头绪,请问大家一些转化的简单 ...… 查看全部问答> |
|
要求:单片机I/0口接4个开关、1个数码管和M95320,两个开关用于改变数码管上的显示数字,1个开关用于将数码管上的值写入到M95320,另外1个开关用于将存储在M95320中的值读取上来,并在数码管中显示。 两个开关用于改变的已经做好了,就是对M95 ...… 查看全部问答> |
|
求助:PC 的并口(LPT1) 和串口哪个速度快一些啊?谢谢2! 请教: PC 的并口(LPT1) 和串口 哪个稳定些? 速度快些? 并口(LPT1)可以做 I/O 口使用,是不? 还有,请给个有这方面资料的网址啊 ^_^ 谢谢!… 查看全部问答> |
|
如题,我用cypress的芯片控制nand flash,型号是k9f1g08u0a,gpif波形图如下,现在我换了一个flash,时序上不一样,没弄过这些,不知道这些图形都代表什么,盼高手指点。 d:\\flash\\gpif\\1.jpg d:\\flash\\gpif\\2.jpg d:\\flash\\gpif\\3.jpg ...… 查看全部问答> |




