STM32 串口3使用代码
来源:互联网 发布:日历软件下载 编辑:程序博客网 时间:2024/05/16 18:44
文章转载http://bbs.21ic.com/icview-850883-1-1.html
有用过STM32F103C8T6 USART3的兄弟吗?? 今天我测试这个模块,发现PB11作为rx可以收到数据,并中断,但PB10却发不出数据,奇怪
void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)
{
//检查参数合法性
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器
//用于标识向量表是在CODE区还是在RAM区
}
//设置NVIC分组
//NVIC_Group:NVIC分组 0~4 总共5组
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
u32 temp,temp1;
temp1=(~NVIC_Group)&0x07;//取后三位
temp1<<=8;
temp=SCB->AIRCR; //读取先前的设置
temp&=0X0000F8FF; //清空先前分组
temp|=0X05FA0000; //写入钥匙
temp|=temp1;
SCB->AIRCR=temp; //设置分组
}
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
{
u32 temp;
u8 IPRADDR=NVIC_Channel/4; //每组只能存4个,得到组地址
u8 IPROFFSET=NVIC_Channel%4;//在组内的偏移
IPROFFSET=IPROFFSET*8+4; //得到偏移的确切位置
MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf;//取低四位
if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位(要清除的话,相反操作就OK)
else NVIC->ISER[1]|=1<<(NVIC_Channel-32);
//NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级和抢断优先级
NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;
}
//不能在这里执行所有外设复位!否则至少引起串口不工作.
//把所有时钟寄存器复位
void MYRCC_DeInit(void)
{
RCC->APB1RSTR = 0x00000000;//复位结束
RCC->APB2RSTR = 0x00000000;
RCC->AHBENR = 0x00000014; //flash时钟,闪存时钟使能.DMA时钟关闭
RCC->APB2ENR = 0x00000000; //外设时钟关闭.
RCC->APB1ENR = 0x00000000;
RCC->CR |= 0x00000001; //使能内部高速时钟HSION
RCC->CFGR &= 0xF8FF0000; //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
RCC->CR &= 0xFEF6FFFF; //复位HSEON,CSSON,PLLON
RCC->CR &= 0xFFFBFFFF; //复位HSEBYP
RCC->CFGR &= 0xFF80FFFF; //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
RCC->CIR = 0x00000000; //关闭所有中断
//配置向量表
MY_NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
}
void Stm32_Clock_Init(unsigned char PLL)
{
unsigned char temp=0;
MYRCC_DeInit(); //复位并配置向量表
RCC->CR|=0x00010000; //外部高速时钟使能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪
RCC->CFGR=0X00000000; //APB1/2=DIV2;AHB=DIV1;
PLL-=2;//抵消2个单位
RCC->CFGR|=PLL<<18; //设置PLL值 2~16
RCC->CFGR|=1<<16; //PLLSRC ON
FLASH->ACR|=0x32; //FLASH 2个延时周期
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));//等待PLL锁定
RCC->CFGR|=0x00000002;//PLL作为系统时钟
while(temp!=0x02) //等待PLL作为系统时钟设置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
void Stm32_Gpio_Init(void)
{
RCC->APB2ENR|=0XFFFF; //GPIO CLOCK EN;
RCC->APB1ENR|=0Xffffffff; //GPIO CLOCK EN;
//4 INPUT;3 OUT PUT
GPIOA->CRL=0x33334b00;
GPIOA->CRH=0x000348b0;
GPIOB->CRL=0x40000000;
//GPIOB->CRH=0x00004b44;
GPIOB->CRH=0x00008f44;
// AFIO->MAPR=0X00;
}
void uart3_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB1ENR|=1<<18; //使能串口时钟
RCC->APB1RSTR|=1<<18; //复位串口1
RCC->APB1RSTR&=~(1<<18);//停止复位
//波特率设置
USART3->BRR=mantissa; // 波特率设置
USART3->CR1|=0X200C; //1位停止,无校验位
USART3->CR1|=1<<8; //PE中断使能
USART3->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(7,0,USART3_IRQChannel,4);//组2,最低优先级
}
void usart3_send8bit(unsigned char indata )
{
while (!(USART3->SR & USART_FLAG_TXE));
USART3->DR = (indata& 0x1FF);
while (!(USART3->SR & USART_FLAG_TC));
}
main ()
{
unsigned int test_data=0;
Stm32_Clock_Init(9);
Stm32_Gpio_Init();
uart3_init(72,9600);
led2=1;
led3=1;
while(1)
{
led1++;
delay1ms(10);
usart3_send8bit(0);
delay1ms(10);
//usart1_send8bit(0);
}
}
我把USART2的TX连到PB11上,USART3可以进入中断,而且收到的数据正确,就是PB10发不出数,
usart3的代码是在STM32f103vet6上用过的, 问题出在哪里呢
这个程序时钟有问题,修改 RCC->APB2ENR=0X481D; //GPIO CLOCK EN;
RCC->APB1ENR=0X12060801; //GPIO CLOCK EN;
就行了
我的程序是定时发送数据,程序是这样的:
u16 temp;
u8 TX_temp[3];
u8 t;
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)
{
temp=DS18B20_Get_Temp();
TX_temp[0]=(u8)temp;
temp=temp>>8;
TX_temp[1]=(u8)temp;
for(t=0;t<2;t++)
{
USART1->DR=TX_temp[t];
while((USART1->SR&0X40)==0);
}
}
TIM3->SR&=~(1<<0);
}
我查看变量temp和TX_temp的值都是对的,但是USART1->DR寄存器的值却一直都是0?
我也不知道为啥,求指点
乱码一般是波特率的原因.
串口3的时钟是串口1的一半.
在<<不完全手册>>2.7.3节,有这么一段话:
void USART1_IRQHandler(void)函数是一个串口1中断响应函数,当串口1发生了相应的中断后,就会跳到该函数执行。这里我们设计了一个小小的接收协议:通过这个函数,配合一个数组USART_RX_BUF[64],一个接收状态寄存器USART_RX_STA实现对串口数据的接收管理。USART_RX_BUF的最大值为64,也就是一次接收的数据最大不能超过64个字节。USART_RX_STA是一个接收状态寄存器其各的定义如下表:
USART_RX_STA
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
接收完成标志
接收 到0X0D标志
接收到的有效数据个数
表2.7.2.2 接收状态寄存器位定义表
设计思路如下:
当接收到从电脑发过来的数据,把接收到的数据保存在USART_RX_BUF中,同时在接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(0X0D,0X0A)的第一个字节0X0D时,计数器将不再增加,等待0X0A的到来,而如果0X0A没有来到,则认为这次接收失败,重新开始下一次接收。如果顺利接收到0X0A,则标记USART_RX_STA的第七位,这样完成一次接收,并等待该位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到0X0D,那么在接收数据超过64个了,则会丢弃前面的数据,重新接收。
- STM32 串口3使用代码
- STM32串口中断使用
- STM32串口中断使用
- STM32串口使用
- STM32 串口接收中断 代码
- STM32下串口的使用
- STM32 串口+DMA的使用
- 在STM32使用串口printf
- stm32 串口的使用-转转
- STM32之串口的使用
- STM32串口使用Printf()函数问题
- STM32学习之串口的使用
- STM32学习之串口的使用
- STM32中使用printf打印串口数据
- STM32串口使用Printf()函数问题
- STM32串口接收使用DMA双缓冲
- 使用STM32的串口进行大量数据传输
- STM32 使用printf打印串口信息
- 项目开发笔记
- 花钱大师
- Shell break和continue命令
- 【LVL1_7_c】【思考题】【2】什么是溢出?什么是内存泄漏?
- 【Linux】 CPU亲和性(affinity)及与亲和性有关的两个函数 sched_setaffinity()和 sched_getaffinity()
- STM32 串口3使用代码
- 第一个Vert.x 3应用程序
- 最新版OpenWrt编译教程,解决依赖问题
- boundField 格式化时间为24小时制
- log4net使用简单小结
- 配置使用连接池的httpClient
- Android软键盘弹出时把布局顶上去的解决方法
- 浅析正则表达式
- 关于SpyDroid