|
帮忙分析下,串口调试助手怎么显示乱码,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);
}
}
|
|