搜索
bottom↓
回复: 8

UART的初始化咋就不行呢???

[复制链接]

出0入0汤圆

发表于 2013-5-29 14:47:12 | 显示全部楼层 |阅读模式
各位老大,帮忙看一眼,我的UART初始化配置有问题吗?

晶振是14M的

怎么就是发不出去,我用的是串口调试工具来测试的,什么都收不到。

void uart_init() {


    UBRR0 = 90 ;
    UCSR0B = (1<< RXEN0) | (1 << TXEN0);                // enable RX & TX
    UCSR0C = (1 << UCSZ00) | (1<<UCSZ01); // 8 bit data, 2 stop bit, no check
       

}

同时在发送函数如下:

void usart_trans(unsigned char data)
{
while(!(UCSR0A&(1<<UDRE0)))

UDR0=data;

}

谢谢.

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-5-29 15:35:58 | 显示全部楼层
UBRR=?  波特率没选呢

出0入0汤圆

 楼主| 发表于 2013-5-29 16:06:37 | 显示全部楼层
xuboluan 发表于 2013-5-29 15:35
UBRR=?  波特率没选呢

UBRR0 = 90 ; 这不是定义了波特率9600吗? 我是用ICC AVR算出来,呵呵.

出0入0汤圆

发表于 2013-5-29 22:00:12 | 显示全部楼层
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);// 8 bit data, 2 stop bit, no check (Atmega 16A)

出10入23汤圆

发表于 2013-5-29 22:20:35 | 显示全部楼层
楼上正解,UCSRC和URRH在同一个IO空间,靠URSEL位来分别,以下摘自datasheet(中文版153页):
“UCSRC寄存器与UBRRH寄存器共用相同的I/O地址。对该寄存器的访问,请参见P151“访
问UBRRH/ UCSRC 寄存器” 。
• Bit 7 – URSEL: 寄存器选择
通过该位选择访问UCSRC 寄存器或UBRRH 寄存器。当读UCSRC 时,该位为1 ;当
写UCSRC 时, URSEL 为1。”

出0入0汤圆

发表于 2013-5-29 22:41:20 | 显示全部楼层
本帖最后由 WANG_JINLONG 于 2013-5-29 22:42 编辑

#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "stdio.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//串口1初始化                  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//LC STUDIO开发板                  
//
//电话:
//修改日期:2013/05/20
//版权所有,盗版必究。
//********************************************************************************
//V1.3修改说明
//支持适应不同频率下的串口波特率设置.
//加入了对printf的支持
//增加了串口接收命令功能.
//修正了printf第一个字符丢失的bug
//////////////////////////////////////////////////////////////////////////////////           


//////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB          
#if 1
#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
        int handle;
        /* Whatever you require here. If the only file you are using is */
        /* standard output using printf() for debugging, no file handling */
        /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{      
        while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
        USART1->DR = (u8) ch;      
        return ch;
}
#endif
//end
//////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////
//串口2中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误          
u8 USART_RX_BUF[64];     //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0;       //接收状态标记          
//串口2中断函数
void USART2_IRQHandler(void)
{
        //u8 com=0;       
            
        if(USART2->SR&(1<<5))//接收到数据
        {         
          //com=USART1->DR;
         // if(com !=0)                    
         //{                         
                  USART2->SR=0<<5;      
              LED_DA2=!LED_DA2;            
              //Uart2_PutChar(0xA5);
                  //Uart2_PutChar(0x97);                                                       
        // }
        }                                                                                         
}
/////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////
//串口2发送函数
//
void Uart2_PutChar(u8 ch)
{
  USART2->DR=ch;
  while((USART2->SR&0X40)==0);//等待发送结束
}
//////////////////////////////////////////////////////////////////////       


///////////////////////////////////////////////////////////////////////                                                                 
//初始化IO 串口2
//pclk2:PCLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk1,u32 bound)
{           
        float temp;
        u16 mantissa;
        u16 fraction;
        //换算波特率          
        temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV
        mantissa=temp;                                 //得到整数部分
        fraction=(temp-mantissa)*16; //得到小数部分         
    mantissa<<=4;
        mantissa+=fraction;
        //使能并配置PA2,PA3.
        RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
        RCC->APB1ENR|=1<<17;  //使能串口2时钟
        GPIOA->CRL&=0XFFFF00FF; //PA2:TX-OUT  PA3:RX-IN
        GPIOA->CRL|=0X00008B00; //PA2:50M开漏 PA3:上拉
        //GPIOA->ODR|=1<<2;                //输出高电平
        GPIOA->ODR|=1<<3;                //上拉输出高电平

        //复位串口2          
        RCC->APB1RSTR|=1<<17;   //复位串口2
        RCC->APB1RSTR&=~(1<<17);//停止复位                     
        //波特率设置
        USART2->BRR=mantissa; // 波特率设置         
        USART2->CR1|=0X200C;  //1位停止,无校验位.
        //使能接收中断
        USART2->CR1|=1<<8;    //PE中断使能
        USART2->CR1|=1<<5;    //接收缓冲区非空中断使能                   
        MY_NVIC_Init(3,3,USART2_IRQChannel,2);//组2,最低优先级
}


#ifndef __USART_H
#define __USART_H
#include <stm32f10x_lib.h>
#include "stdio.h"         
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//LC STUDIO开发板
//按键输入 驱动代码                  
//
//电话:
//修改日期:2013/05/20
//版权所有,盗版必究。
//********************************************************************************
//V1.3修改说明
//支持适应不同频率下的串口波特率设置.
//加入了对printf的支持
//增加了串口接收命令功能.
//修正了printf第一个字符丢失的bug
//////////////////////////////////////////////////////////////////////////////////           

                 
extern u8 USART_RX_BUF[64];     //接收缓冲,最大63个字节.末字节为换行符
extern u8 USART_RX_STA;         //接收状态标记       

//如果想串口中断接收,请不要注释以下宏定义
#define EN_USART1_RX         1;                //使能(1)/禁止(0)串口1接收
void uart_init(u32 pclk2,u32 bound);
void Uart2_PutChar(u8 ch);

#endif          


你参考一下,这是测试串口2用的,没有仔细的写,只是证明能通

出0入0汤圆

发表于 2013-5-29 23:24:36 | 显示全部楼层
while(!(UCSR0A&(1<<UDRE0)))                    ---------------少个';'号吧。。。
UDR0=data;

这样会不断的启动发送,实际是发不出去的。

出200入2554汤圆

发表于 2013-5-30 01:30:16 | 显示全部楼层
LS正解啊。

有些编译器写 UBRR0 的时候,直接是包含了 [UBRR0H:UBRR0L] 的16位访问模式,
可以直接赋值给高低8位的。

出0入0汤圆

 楼主| 发表于 2013-5-30 08:29:12 | 显示全部楼层
mitchell 发表于 2013-5-29 23:24
while(!(UCSR0A&(1

Mitchell兄正解,果然是少了个;,大意啊.....  也谢谢其余几位坛友的关注与帮忙.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 01:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表