打印
[STM32F1]

STM32F103C8T6 USART3 问题

[复制链接]
8645|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
clz918|  楼主 | 2014-12-17 10:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 clz918 于 2014-12-17 10:12 编辑

有用过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上用过的, 问题出在哪里呢




沙发
1021256354| | 2014-12-17 10:48 | 只看该作者
看起来好乱啊,时钟-端口复用-接收发送使能-中断就这几块,自己再查查.

使用特权

评论回复
板凳
clz918|  楼主 | 2014-12-17 10:53 | 只看该作者
1021256354 发表于 2014-12-17 10:48
看起来好乱啊,时钟-端口复用-接收发送使能-中断就这几块,自己再查查.

谢谢提醒,可能是习惯吧,不喜欢用库函数

使用特权

评论回复
地板
clz918|  楼主 | 2014-12-17 11:18 | 只看该作者
1021256354 发表于 2014-12-17 10:48
看起来好乱啊,时钟-端口复用-接收发送使能-中断就这几块,自己再查查.

果真是时钟的问题,修改   RCC->APB2ENR=0X481D;   //GPIO CLOCK EN;
                        RCC->APB1ENR=0X12060801;   //GPIO CLOCK EN;
就行了

使用特权

评论回复
5
mmuuss586| | 2014-12-17 12:26 | 只看该作者

解决了就好,说明还是你程序问题啊;

使用特权

评论回复
6
clz918|  楼主 | 2014-12-17 12:51 | 只看该作者
mmuuss586 发表于 2014-12-17 12:26
解决了就好,说明还是你程序问题啊;

呵呵,曾经怀疑是片子本身的问题,

使用特权

评论回复
7
airwill| | 2014-12-17 21:44 | 只看该作者
路过, 看到又是一大段寄存器操作引起的问题.
建议写这样的代码的时候, 尽量多使用库里的宏, 不要直接写数字 (这样查错误太麻烦). 举例:
RCC->APB1ENR|=1<<18;  //使能串口时钟
你可以写成
RCC->APB1ENR|= RCC_APB1Periph_USART3;  //使能串口3时钟

使用特权

评论回复
8
clz918|  楼主 | 2014-12-18 08:38 | 只看该作者
airwill 发表于 2014-12-17 21:44
路过, 看到又是一大段寄存器操作引起的问题.
建议写这样的代码的时候, 尽量多使用库里的宏, 不要直接写数 ...

好办法

使用特权

评论回复
9
三又二分之一7| | 2015-11-7 20:47 | 只看该作者
请问楼主是怎么解决的,我也是不能发送,找不到原因

使用特权

评论回复
10
gejigeji521| | 2017-10-5 12:23 | 只看该作者
楼主 现在成高手了 吧,分享一下代码啊,经验。

使用特权

评论回复
11
chenqiang10| | 2017-10-5 17:18 | 只看该作者
时钟配置问题,你这个应该是没打开。

使用特权

评论回复
12
ihafd| | 2017-10-6 10:46 | 只看该作者
路过,发现问题已经解决.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

336

帖子

3

粉丝