10666|1

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

帮忙分析下,串口调试助手怎么显示乱码,xiexie [复制链接]

外接晶振 8MHz
/***********************************************
****      AVR  DS18B20范例           ***
**** MCU: ATmega16                           ***
**** 作者:  maweili                        ***
**** 编译器:WINAVR                   ***
****                                         ***
****          2008.11.27           ***
***********************************************/

#include         
#include
#include    //中断函数头文件

//××××××××××××引脚宏定义×××××××××××××
//18B20定义
#define SET_DQ (PORTA) |= (1 << (PA2))      // 18b20 高电平
#define CLR_DQ (PORTA) &=~(1 << (PA2))      // 18b20 低电平
#define DQ_IN  (PINA) & (1<<(PA2))            // 18b20信号输入

#define SET_OUT (DDRA)|= (1<<(PA2))         //PA2定义成输出
#define SET_IN  (DDRA)&=~(1<<(PA2))         //PA2定义成输入



//常量声明
#define BAUD 9600

//全局变量声明
unsigned char Temp_H,Temp_L,OK_Flag;

//函数声明
void Delayus(unsigned int lus);
void Delayms(unsigned int lms);
void Port_Init(void);   //端口初始化配置
void Usart_Init(void);  //USART寄存器设置
void Usart_PutChar(unsigned char cTXData);  //字节发送函数
void Usart_PutString(unsigned char *pcString);
void Usart_PutString(unsigned char *pcString);



unsigned char DS18B20_Init(void);
unsigned char Read_18b20(void);        //读18b20
void Write_18b20(unsigned char dat);   //写18b20

int main(void)            
{
        unsigned char i;
        unsigned int tempint,temppoint;  //temp用于存储温度值,
                                 //tempint用于存储温度整数值,temppoint用于存储温度小数值,
       
        Port_Init();
        Usart_Init();
       
        tempint = 0;
        temppoint=0;
        Temp_H = 0;
        Temp_L = 0;
        OK_Flag = 0;
       
        Usart_PutString((unsigned char *)"DS18B20 温度测量实验");
        Usart_PutChar(0x0D);
        Usart_PutChar(0x0A);  //结尾发送回车换行
       
       
        sei();          //使能全局中断  
       
        while(1)
        {                       
                /*
                if(DS18B20_Init())
                {
                        PORTB = 0x01;
                }
                else
                {
                        PORTB = 0x02;
                }
                */
                cli();
                DS18B20_Init();     //初始化DS18B20
               
                Write_18b20(0Xcc);  //发送ROM指令,跳过ROM匹配
               
                Write_18b20(0X44);  //               
               
                for(i=0;i<50;i++)      //延时等转换完成
                {
                        Delayms(20);
                }
               
                DS18B20_Init();    //初始化DS18B20
               
                Write_18b20(0Xcc);  //发送ROM指令,跳过ROM匹配
               
                Write_18b20(0Xbe);  //发送读取暂存器指令
                       
                Temp_L = Read_18b20(); //获得温度的低位
               
                Temp_H = Read_18b20(); //获得温度的高位
                       
                if(Temp_H & 0x08)   //判断温度的正负
                {
                        PORTB = 0x04;
                        Temp_H = ~Temp_H;  //负温度。取反加1
                        Temp_L = ~Temp_L;  //
               
                        SREG |= ~(1 << SREG_C);  //清零进位位标志
                        Temp_L++;                  //温度低字节加1
                        if(SREG & (1 << SREG_C))  //有进位吗?
                        {
                                Temp_H++;           //有进位,则温度高字节加1
                        }
               
                }       
                PORTB |= (1 << PB1);
                temppoint = Temp_L & 0x0f;
               
                tempint = ((Temp_H << 4) & 0x70) | (Temp_L >> 4);               
               
                Usart_PutString((unsigned char *)"当前环境温度为:");
                Usart_PutChar(tempint / 1000 + 0x30);
                Usart_PutChar(tempint % 1000 / 100 + 0x30);
                Usart_PutChar(tempint % 100 / 10 + 0x30);
                Usart_PutChar(tempint % 10 + 0x30);
       
                Usart_PutChar(0x0D);
                Usart_PutChar(0x0A);  //结尾发送回车换行       
        
                sei();

                for(i=0;i<200;i++)      //
                {
                        Delayms(20);
                }
        }
}

//端口状态初始化设置函数
void Port_Init()
{
        PORTD = 0X00;          //USART的发送接收端口分别为PD0和PD1
        DDRD |= (0 << PD1);   //PD0为接收端口,置为输入口;PD1为发送端口,置为输出口
    DDRD |= (1 << PD0);

        PORTB = 0x00;
        DDRB = 0xff;
       
        DDRA &= ~(1 << PA2);// 输入模式(上电时为高电平)
    PORTA &= ~(1 << PA2);// 输出锁存器写0,以后不再更改
}

//USART寄存器配置函数
void Usart_Init()
{
        UCSRA = 0X00;       
        UCSRC |= (1<              //UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,写 UCSRC 时, URSEL 应设置为 1。
        UBRRL = (F_CPU / BAUD / 16 - 1) % 256;    //波特率设置
        UBRRH = (F_CPU / BAUD / 16 - 1) / 256;               
        UCSRB |= (1 << RXCIE) | (1 << RXEN) | (1 << TXEN);    //发送使能
       
}

//字节发送函数
void Usart_PutChar(unsigned char cTXData)
{
        while( !(UCSRA & (1 << UDRE)) );  //只有数据寄存器为空时才能发送数据
        UDR = cTXData;                         //发送数据送USART I/O数据寄存器-UDR
}

//接收中断函数
ISR(USART_RXC_vect )
{
        unsigned char Rev;
        Rev = UDR;              //从USART I/O数据寄存器-UDR中读出数据
        Usart_PutChar(Rev);    //将接收到的数据发送
}


void Usart_PutString(unsigned char *pcString)
{
        while (*pcString)
        {
                Usart_PutChar(*pcString++);
        }       
}

//DS18B20初始化
unsigned char DS18B20_Init()
{
        //unsigned char Delayus0;
       
        SET_OUT;   //PA2设置为输出口
        CLR_DQ;    //输出低               
       
       
        Delayus(560);
       
       
        SET_DQ;
        SET_IN;     //输入 释放数据线
       
        Delayus(90);
       
               
        //while(DQ_IN);
       
        //while(!(DQ_IN));       
       
        if(DQ_IN)
        {
                OK_Flag = 0;                       
        }
        else
        {
                OK_Flag = 1;               
        }
       
        Delayus(400);
       
        SET_OUT;
        SET_DQ;       
       
        return OK_Flag;
}

unsigned char Read_18b20()
{
        unsigned char i;   // dat用于存储读到的数据
        unsigned char dat = 0;   // dat用于存储读到的数据       
       
        for(i = 0;i < 8;i++)
        {
                CLR_DQ;
                SET_OUT;    //定义为输出
               
                Delayus(5);   //拉低15微秒
               
                SET_DQ;      //拉高
                SET_IN;        //定义成输入,读入数据
                       
                Delayus(15);
                       
                if(DQ_IN)       //读数据
                {                       
                        dat |= 0x80;   //如果是1,置1,右移数据
                }
                Delayus(65);
                SET_DQ;      //拉高
                SET_OUT;    //定义为输出
                Delayus(1);
                dat = dat >> 1;
               
        }       
        return dat;     //返回读到的1字节数据
}

void Write_18b20(unsigned char dat)
{
        unsigned char i;
       
        SET_OUT;            //数据线设置为输出
        for(i = 0;i < 8;i++)  
        {
                CLR_DQ;         //拉低数据线15us,开始写数据
                Delayus(10);
               
                if(dat & 0x01)   //写数据
                {
                        SET_DQ;    //写1                       
                }
                else
                {
                        CLR_DQ;   //写0                       
                }
               
                Delayus(65);
                       
                SET_DQ;          //拉高数据线
                Delayus(10);   //写两位数据的时间间隔
                dat >>= 1;      //数据右移1位,先写低位
        }
        SET_DQ;         //拉高
        //PORTB = 0x01;       
}

void Delayus(unsigned int lus)
{
        while(lus--)
        {
                _delay_loop_2(3);
    }
}


void Delayms(unsigned int lms)
{
        while(lms--)
        {
                Delayus(1000);
    }
}
此帖出自单片机论坛

最新回复

注意数制的正确选择,包括程序中和串口调试软件的。  详情 回复 发表于 2012-3-22 18:49
点赞 关注
 

回复
举报

1万

帖子

141

TA的资源

版主

沙发
 
注意数制的正确选择,包括程序中和串口调试软件的。
此帖出自单片机论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表