搜索
bottom↓
回复: 17

请教:Usart的数据位个数的设定?

[复制链接]

出0入0汤圆

发表于 2006-2-6 20:34:27 | 显示全部楼层 |阅读模式
USART用于控制数据位个数的寄存器

UCSRB 中的(2)UCSZ2

UCSRC 中的(2)UCSZ1,(1)UCSZ0



UCSZ2,UCSZ1,UCSZ0 由高到低设置数据的个数5,6,7,8,9



请问:3个位真值表 对应 5,6 ,7,8,9 个数据位的设定时怎么样的呢?



查了几本书,要不没有说;要么就是一带而过。



目前只知道

2 1 0          个数

------------------------

0 0 0           8



谢谢!

出0入0汤圆

发表于 2006-2-6 21:24:18 | 显示全部楼层
UCSZ1:0与UCSRB寄存器的UCSZ2结合在一起可以设置数据帧包含的数据位数(字符长度)。



table 58. UCSZ 设置

UCSZ2 UCSZ1 UCSZ0 字符长度

  0     0     0    5位

  0     0     1    6位

  0     1     0    7位

  0     1     1    8位

  1     0     0    保留

  1     0     1    保留

  1     1     0    保留

  1     1     1    9位



每份AVR数据手册都有图表说明,请认真看,好吗?

出0入0汤圆

 楼主| 发表于 2006-2-6 21:51:37 | 显示全部楼层
谢谢!HJJourAVR老大,这么晚还没有回去啊?



但是我这里与 串口调试助手 设定的不一样:

串口调试助手:8位(默认)

avr中需要设为 UCSZ2 = 0,UCSZ1 = 0, UCSZ0 = 0,才能通信,否则数据不对!!



我再去看看,如果不行再来请教!

出0入0汤圆

发表于 2006-2-6 22:14:39 | 显示全部楼层
那请问你的程序怎么理解?

case DATA_BIT_8://

         UCSRC |= _BV(UCSZ0);

         UCSRC |= _BV(UCSZ1);

         break;

出0入0汤圆

 楼主| 发表于 2006-2-6 22:28:18 | 显示全部楼层
Uart.c主程序



#include <avr/io.h>

#include <avr/delay.h>

#include "../Common/UartCom/UartCom.h" //Uart串口异步通信处理头文件





int main(void)

{       

        unsigned char TmpData;

        Usart_InitDef(4800);



       

        Usart_PutStr("Hello");

       

        while(1)

        {

                TmpData=Usart_GetChar();               

                Usart_PutChar(TmpData);       

               

        }

}



/*************** UartCom.h 文件*******************************/

#ifndef _UART_COM_H_

#define _UART_COM_H_

/*****************************

Uart串口异步通信处理头文件

****************************/



//定义8位数据类型 BYTE

#define BYTE unsigned char



//校验位

#define VERIFY_TYPE_NONE         0        //无校验

#define VERIFY_TYPE_EVEN        2        //偶校验

#define VERIFY_TYPE_ODD                3        //奇校验



//数据位个数(推测)

#define DATA_BIT_5                0

#define DATA_BIT_6                1

#define DATA_BIT_7                2

#define DATA_BIT_8                3

#define DATA_BIT_9                4



//停止位

#define STOP_BIT_1        0        //1位停止位

#define STOP_BIT_2        1        //2位停止位



#define Usart_InitDef(iBaudRate) \

                Usart_Init(iBaudRate,VERIFY_TYPE_NONE,DATA_BIT_8,STOP_BIT_1)



//初始化Uart(设置:波特率,检验位,数据位,停止位)

void Usart_Init(int iBaudRate,BYTE iVerifyType,

                                BYTE iDataBitType,

                                BYTE iStopBitType);

                               



//发送1个字符

void Usart_PutChar(BYTE iData);

//接收1个字符

BYTE Usart_GetChar(void);



//发送一串字符

void Usart_PutStr(char* pStr);



#endif



/*************** UartCom.c 文件*******************************/

#include "UartCom.h"



#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <avr/delay.h>



//USART寄存器介绍*******************

/*

1.USART数据寄存器 UDR

        RXB

        TXB        

*/

/*

2.USART控制和状态寄存器A -- UCSRA

7 - RXC                :        USART接收完成

6 - TXC                :         USART发送完成

5 - UDRE        :        USART数据寄存器空

4 - FE                :        接收帧出错

3 - DOR                :        接收数据溢出出错

2 - PE                :        校验错误

1 - U2X                :        USART传输速率倍速

0 - MPCM        :        多机通信模式允许

*/

/*

3.USART控制和状态寄存器B -- UCSRB

7 - RXCIE                :        RX 接收完成中断允许

6 - TXCIE                :         TX 发送完成中断允许

5 - UDRIE                :        USART数据寄存器空中断允许

4 - RXEN                :        数据接收允许

3 - TXEN                :        发送数据允许

2 - UCSZ2                :        数据位数大小

1 - RXB8                :        接收数据的第8位

0 - TXB8                :        发送数据的第8位

*/

/*

4.USART控制和状态寄存器C -- UCSRC

7 - URSEL                :        寄存器选择

6 - UMSEL                :         USART工作模式选择

5 - UPM1                :        5..4校验方式

4 - UPM0                :        5..4校验方式

3 - USBS                :        停止位选择

2 - UCSZ1                :        2..1创送或接收字符长度

1 - UCSZ0                :        2..1创送或接收字符长度

0 - UCPOL                :        时钟极性

*/

/*

5.波特率寄存器 -- UBRRL和 UBRRH

15 - URSEL                :        寄存器选择

14,13,12 -- 保留 = 设为0

11....0        USART波特率设置寄存器

*/



/*

//数据位

UCSZ2 UCSZ1 UCSZ0 字符长度

  0     0     0    5位

  0     0     1    6位

  0     1     0    7位

  0     1     1    8位

  1     0     0    保留

  1     0     1    保留

  1     1     0    保留

  1     1     1    9位

*/



//USART需要发送的数据是否准备好

#define USART_DATA_IS_READY (UCSRA & (1<<UDRE))

//USART数据接收是否完成

#define USART_DATA_RECV_IS_OK (UCSRA & (1<<RXC))



//初始化Uart(设置:波特率,检验位,数据位,停止位)

void Usart_Init(int iBaudRate,BYTE iVerifyType,

                                BYTE iDataBitType,BYTE iStopBitType)

{//Uart初始化



        //清除状态

        UCSRA=0x00;

        //处理波特率,此时URSEL = 0;

        UBRRL= (F_CPU/iBaudRate/16-1)%256;

    UBRRH= (F_CPU/iBaudRate/16-1)/256;

       

       

        //设置USCRB

        UCSRB = _BV(RXCIE)|_BV(TXCIE)|_BV(RXEN)|_BV(TXEN);

       

        //设置校验位

        UCSRC&=~_BV(UMSEL);//异步模式

        UCSRC&=~_BV(UCPOL);//XCK下降沿

       

       

        switch(iVerifyType)

        {

                case  VERIFY_TYPE_NONE://无校验

                        UCSRC &= ~_BV(UPM0);

                        UCSRC &= ~_BV(UPM1);       

                        break;

                case VERIFY_TYPE_EVEN://偶校验

                        UCSRC &= ~_BV(UPM0);

                        UCSRC |= _BV(UPM1);       

                        break;

                case VERIFY_TYPE_ODD://奇校验

                        UCSRC |= _BV(UPM0);

                        UCSRC |= _BV(UPM1);       

                        break;

                default:

                        UCSRC &= ~_BV(UPM0);

                        UCSRC &= ~_BV(UPM1);       

        }

       

       



        /********************************

         //该段注释了

        //数据位

        switch(iDataBitType)

        {

                case  DATA_BIT_5:

                        UCSRC &= ~_BV(UCSZ0);

                        UCSRC &= ~_BV(UCSZ1);       

                        break;

                case DATA_BIT_6://

                        UCSRC |= _BV(UCSZ0);

                        UCSRC &= ~_BV(UCSZ1);

                        break;

                case DATA_BIT_7://

                        UCSRC &= ~_BV(UCSZ0);

                        UCSRC |= _BV(UCSZ1);

                        break;

                case DATA_BIT_8://

                        UCSRC |= _BV(UCSZ0);  //UCSZ0位置 1

                        UCSRC |= _BV(UCSZ1);  //UCSZ1位置 1

                        break;               

                case DATA_BIT_9://

                        UCSRC &= ~_BV(UCSZ0);

                        UCSRC &= ~_BV(UCSZ1);

                        UCSRB |= _BV(UCSZ2);

                        break;

                default:

                        UCSRC |= _BV(UCSZ0);

                        UCSRC |= _BV(UCSZ1);       

        }

       

        *******************************/



       

        //停止位

        if(iStopBitType == STOP_BIT_2)

                UCSRC |= _BV(USBS);

        else

                UCSRC &=~_BV(USBS);       

               

        //sei();//总中断允许

       

        _delay_ms(20);



}

//发送1个字符

void Usart_PutChar(BYTE iData)

{       

        while( !USART_DATA_IS_READY ); //数据如果没有准备好,则等待

        UDR=iData;       

}

//接收1个字符

BYTE Usart_GetChar(void)

{

        BYTE RetData;

        while( !USART_DATA_RECV_IS_OK );

        RetData = UDR;

        return RetData;

}

       

//发送一串字符

void Usart_PutStr(char* pStr)

{

        while(*pStr)

        {

                Usart_PutChar(*pStr);

                pStr++;

        }

}

出0入0汤圆

发表于 2006-2-6 23:11:19 | 显示全部楼层
唉,是你自己没看手册。

请注意:上电默认 UCSZ2=0 UCSZ1=1 UCSZ0=1 即 8位数据长度。

出0入0汤圆

 楼主| 发表于 2006-2-6 23:43:28 | 显示全部楼层
但是,我已经注释掉了,那段没有起作用的,还有我最后返回了ucsrc = 0

出0入0汤圆

发表于 2006-2-7 00:17:41 | 显示全部楼层
注释掉了,没修改不就等于上电默认值吗?

上电默认 UCSZ2=0 UCSZ1=1 UCSZ0=1 即 8位数据长度





[返回了ucsrc = 0] 哪里?

出0入0汤圆

发表于 2006-2-7 00:24:19 | 显示全部楼层
手册的UCSZ设定是没有错的,你自己喜欢瞎折腾就慢慢玩吧。

出0入0汤圆

 楼主| 发表于 2006-2-7 09:27:24 | 显示全部楼层
下了atmega8数据手册看了,确实是(3<<UCSZ0) 011

数据手册确实是好东西,明明白白,现在发现好多书的内容都照抄了数据手册。



我的UCSRC=0;是Usart_PutChar(UCSRC);传给串口调试助手显示的(16进制),那样行么?





在主程序中 ,不断返回的

  

   while(1)

   {

      Usart_PutChar(UCSRC);

      

   }

}

出0入0汤圆

发表于 2006-2-7 09:34:53 | 显示全部楼层
一句话,自讨苦吃。还是不愿意认真看手册。

而且网站的新手入门范例里面也明确的用中文注释了使用串口的注意事项,白费蜡!



UBRRH与UCSRC共用I/O 地址。因此访问该地址时需注意以下问题。

    写访问

    当在该地址执行写访问时, USART 寄存器选择位(URSEL)控制被写入的寄存器。

    若URSEL为0,对UBRRH值更新;若URSEL为1,对UCSRC设置更新

   

    读访问

    对UBRRH 或UCSRC 寄存器的读访问则较为复杂。但在大多数应用中,基本不需要读这些寄存器

读访问由时序控制。一旦返回UBRRH 寄存器内容则读I/O 地址。若寄存器地址在前一个

系统时钟周期中读入,当前时钟下对寄存器的读入将返回UCSRC 内容中。注意,读

UCSRC 的时钟序列为自动工作。在读操作中的中断( 例如禁止全局中断) 必须人为控制。

下面代码给出如何读 UCSRC 寄存器内容。



汇编代码例程(1)

USART_ReadUCSRC:

; 读UCSRC

in r16,UBRRH

in r16,UCSRC

ret

C 代码例程(1)

unsigned char USART_ReadUCSRC( void )

{

unsigned char ucsrc;

/* 读UCSRC */

ucsrc = UBRRH;

ucsrc = UCSRC;

return ucsrc;

}

Note: 1. 本代码假定已经包含了相应的头文件。

汇编代码在r16 中返回UCSRC 值。

对UBRRH 内容的读操作不是自动完成,且当前一条指令没有访问该寄存器地址时,该寄

存器作为普通寄存器使用。

出0入0汤圆

 楼主| 发表于 2006-2-7 09:50:54 | 显示全部楼层
多谢HJJourAVR 老大,明白了!!

刚刚也看到。多谢!!

出0入0汤圆

发表于 2006-2-7 21:51:47 | 显示全部楼层
学习ing 。。。各位辛苦,菜鸟们就喜欢看这样务实的讨论啊!

出0入0汤圆

发表于 2009-9-25 11:43:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-25 20:35:31 | 显示全部楼层
串口通信,现在基本上就8位或9位通信。如果是与PC机通信,就是8位了。
串口设置中有5、6、7位的方式,只是为与以前的软件兼容而增加的,在新的程序中,不要去管什么5、6、7位的方式。

出0入0汤圆

发表于 2010-8-12 21:24:17 | 显示全部楼层

出0入0汤圆

发表于 2010-8-12 22:29:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-20 02:39:18 | 显示全部楼层
GOOD
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-8 03:11

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

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