导航:首页 > 操作系统 > 单片机ofe

单片机ofe

发布时间:2025-07-28 08:24:06

1. Proteus仿真单片机测量空气湿度

几点说明:

1.主要是分以下几个模块写的:SHT10,LCD1602,主函数,头文件。

2.每支SHTxx传感器都在25℃(77 °F)和 3.3V条件下进行过标定并且完全符合精度指标.因为考虑到实际硬件5V的电压比较好操作,所以SHT10用的精度采用的为5V时的参数。其他的都采取默认值(14bit湿度, 12bit 温度)。

3.SHT10中所以部分我都编写了。有的部分在本次程序中没用到,也可以作为参考。

4.所有程序都已经加了注释,且有仿真图。

5.个人认为还可以在此基础上添加个中断。

6.程序编写keil 4 ,仿真 protues7.5

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

头文件(tou.h):

#ifndef __TOU_H__

#define __TOU_H__

#include<reg52.h>

#include <intrins.h>

//#include <math.h> //Keil library

#define uchar unsigned char

enum {TEMP,HUMI};

sbit DATA = P1^7;

sbit SCK = P1^6;

sbit LcdRs= P2^4;

sbit LcdRw= P2^5;

sbit LcdEn= P2^6;

sfr DBPort= 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

/******** DS1602函数声明 ********/

void LCD_Initial();

void GotoXY(unsigned char x, unsigned chary);

void Print(unsigned char *str);

void LCD_Write(bit style, unsigned charinput);

/******** SHT10函数声明 ********/

void s_connectionreset(void);

char s_measure(unsigned char *p_value,unsigned char *p_checksum, unsigned char mode);

void calc_sth10(float *p_humidity ,float*p_temperature);

//float calc_dewpoint(float h,float t);

#endif

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

SHT10程序(SHT10.c):

#include<tou.h>

#define noACK 0 //继续传输数据,用于判断是否结束通讯

#define ACK 1//结束数据传输;

//地址命令 读/写

#define STATUS_REG_W 0x06 //0000011 0

#define STATUS_REG_R 0x07 //0000011 1

#define MEASURE_TEMP 0x03 //0000001 1

#define MEASURE_HUMI 0x05 //0000010 1

#define RESET 0x1e//000 1111 0

//写字节程序

char s_write_byte(unsigned char value)

{

unsignedchar i,error=0;

for(i=0x80;i>0;i>>=1)//高位为1,循环右移

{

if(i&value) DATA=1; //和要发送的数相与,结果为发送的位

else DATA=0;

SCK=1;

_nop_();_nop_();_nop_(); //延时3us

SCK=0;

}

DATA=1; //释放数据线

SCK=1;

error=DATA; //检查应答信号,确认通讯正常

_nop_();_nop_();_nop_();

SCK=0;

DATA=1;

returnerror; //error=1 通讯错误

}

//读字节程序

char s_read_byte(unsigned char ack)

//----------------------------------------------------------------------------------

{

unsignedchar i,val=0;

DATA=1; //释放数据线

for(i=0x80;i>0;i>>=1) //高位为1,循环右移

{

SCK=1;

if(DATA) val=(val|i); //读一位数据线的值

SCK=0;

}

DATA=!ack; //如果是校验,读取完后结束通讯;

SCK=1;

_nop_();_nop_();_nop_(); //延时3us

SCK=0;

_nop_();_nop_();_nop_();

DATA=1; //释放数据线

returnval;

}

//启动传输

void s_transstart(void)

// generates a transmission start

//_____ ________

// DATA: |_______|

//___ ___

// SCK : ___| |___||______

{

DATA=1; SCK=0; //准备

_nop_();

SCK=1;

_nop_();

DATA=0;

_nop_();

SCK=0;

_nop_();_nop_();_nop_();

SCK=1;

_nop_();

DATA=1;

_nop_();

SCK=0;

}

//连接复位

void s_connectionreset(void)

// communication reset: DATA-line=1 and atleast 9 SCK cycles followed by transstart

//_____________________________________________________ ________

// DATA:|_______|

//_ _ __ _ __ _ ____ ___

// SCK : __| |__| |__| |__| |__| |__| |__||__| |__| |______| |___| |______

{

unsignedchar i;

DATA=1;SCK=0; //准备

for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位

{

SCK=1;

SCK=0;

}

s_transstart(); //启动传输

}

//软复位程序

char s_softreset(void)

// resets the sensor by a softreset

{

unsignedchar error=0;

s_connectionreset(); //启动连接复位

error+=s_write_byte(RESET); //发送复位命令

returnerror; //error=1 通讯错误

}

/*读状态寄存器

char s_read_statusreg(unsigned char*p_value, unsigned char *p_checksum)

//----------------------------------------------------------------------------------

// reads the status register with checksum(8-bit)

{

unsignedchar error=0;

s_transstart(); //transmission start

error=s_write_byte(STATUS_REG_R);//send command to sensor

*p_value=s_read_byte(ACK); //read status register (8-bit)

*p_checksum=s_read_byte(noACK); //read checksum (8-bit)

returnerror; //error=1 incase of no response form the sensor

}

2. 关于单片机方面的英文文献,最还有翻译

基于单片机的电子表设计
摘要:近年来随着计算机在社会领域的渗透和大规模集成电路的发展,单片机的应用正在不断地走向深入,由于它具有功能强,体积小,功耗低,价格便宜,工作可靠,使用方便等特点,因此特别适合于与控制有关的系统,越来越广泛地应用于自动控制,智能化仪器,仪表,数据采集,军工产品以及家用电器等各个领域,单片机往往是作为一个核心部件来使用,在根据具体硬件结构,以及针对具体应用对象特点的软件结合,以作完善。
本次做的电子表是以单片机(AT89S51)为核心,结合相关的元器件(共阴极LED数码显示器、BCD-锁存/7段译码等),再配以相应的软件,达到实现时钟日历显示的功能,也具有日历计算、显示和时钟、日历的校准,以及多路开关定时输出等功能,其硬件部分难点在于元器件的选择、布局及焊接。
Based on the design of electronic SCM
Abstract: In recent years, with computer penetration in the social sphere and the development of large-scale integrated circuits, MCU applications are constantly deepening, as it has a function of strong, small size, low power consumption, cheap, reliable, Easy to use, and other characteristics, and therefore particularly suited to control the system, more widely used in automatic control, intelligent instruments, meters, data acquisition, military procts and household appliances, and other fields, the MCU is often as a core Parts to use, in accordance with specific hardware and application-specific characteristics of the object with software to make perfect.
This is done in electronic form SCM (AT89S51) as the core, the combination of related components (of cathode LED digital display, BCD-latch / 7 of the decoder, and so on), Coupled with the corresponding software, to achieve Clock calendar shows that the function of the calendar also calculated, display and the clock, the calendar of calibration, and multi-channel Kaiguandingshi output, and other functions, some of its hardware components is difficult choice, layout and welding.

3. 51单片机两个I/O口分别接ds18b20程序

//DS从机程序
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SLAVE 0x01
#define BN 6
sbit LCD_RS = P2^5; /*定义LCD控制端口*/
sbit LCD_RW = P2^6;
sbit LCD_EN = P2^7;

sbit DS1=P1^0;
sbit DS2=P1^1;
sbit key3=P3^5;
sbit tem=P3^3;
sbit win=P3^4;
sbit key1=P3^6;
sbit key2=P3^7;
uint temp1,temp2,tempH,tempL; // variable of temperature
uchar flag1,aa,we;
uchar A1,A2,A3,A4,B1,B2,B3,B4; // sign of the result positive or negative
uchar dis1[16]={76,45,84,'0','0','.','0',32,32,72,45,84,'0','0','.','0'};
uchar dis2[16]={48,49,32,'0','0','.','0',32,32,48,50,32,'0','0','.','0'};
uchar code tab[] = {'0','1','2','3','4','5','6','7','8','9'};
uchar trbuf[6];
bit tready;
bit rready;
void str(void);
void sre(void);

void delay(int ms)
{
int i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}

/*******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/

bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0&0x80);
LCD_EN = 0;
return result;
}

/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/

void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}

/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/

void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}

/*******************************************************************/
/* */
/* 设定显示位置 */
/* */
/*******************************************************************/

void lcd_pos(uchar pos)
{
lcd_wcmd(pos|0x80); //数据指针=80+地址变量
}

/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/

void lcd_init()
{
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);

lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
lcd_wcmd(0x06); //向右移动光标
delay(5);
}

/*******************************************************************/
/* */
/* 闪动子程序 */
/* */
/*******************************************************************/

void flash()
{
delay(600); //控制停留时间
lcd_wcmd(0x08); //关闭显示
delay(200); //延时
lcd_wcmd(0x0c); //开显示
delay(200); //延时
lcd_wcmd(0x08); //关闭显示
delay(200); //延时
lcd_wcmd(0x0c); //开显示
delay(200);
}

/*void delay(uint count) //delay
{
uint i;
while(count)
{
i=100;
while(i>0)
i--;
count--;
}
} */
///////功能:串口初始化,波特率9600,方式1///////
void Init(void)
{
TMOD=0x20;
TL1=0xfd;
TH1=0xfd;
PCON=0x00;
TR1=1;
SCON=0xf0;
ES=1;
EA=1;
}

void dsreset(uchar DS) //send reset and initialization command 18B20复位,初始化函数
{
uint i;
if(DS==1)
{
DS1=0;
i=103;
while(i>0)i--;
DS1=1;
i=4;
while(i>0)i--;
}
if(DS==2)
{
DS2=0;
i=103;
while(i>0)i--;
DS2=1;
i=4;
while(i>0)i--;
}
}

bit tmpreadbit(uchar DS) //read a bit 读DS2 1位数据函数
{
uint i;
bit dat;
if(DS==1)
{
DS1=0;i++; //i++ for delay
DS1=1;i++;i++;
dat=DS1;
i=8;while(i>0)i--;
}
if(DS==2)
{
DS2=0;i++; //i++ for delay
DS2=1;i++;i++;
dat=DS2;
i=8;while(i>0)i--;
}
return (dat);
}

uchar tmpread(uchar DS) //read a byte date 读1字节函数
{
uchar i,j,dat;
dat=0;
if(DS==1)
{
for(i=1;i<=8;i++)
{
j=tmpreadbit(1);
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
}
if(DS==2)
{
for(i=1;i<=8;i++)
{
j=tmpreadbit(2);
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
}
return(dat);
}

void tmpwritebyte(uchar dat,uchar DS) //write a byte to ds18b20 向1820写一个字节数据函数
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(DS==1)
{
if(testb) //write 1
{
DS1=0;
i++;i++;
DS1=1;
i=8;while(i>0)i--;
}
else
{
DS1=0; //write 0
i=8;while(i>0)i--;
DS1=1;
i++;i++;
}
}
if(DS==2)
{
if(testb) //write 1
{
DS2=0;
i++;i++;
DS2=1;
i=8;while(i>0)i--;
}
else
{
DS2=0; //write 0
i=8;while(i>0)i--;
DS2=1;
i++;i++;
}
}
}
}

void tmpchange(uchar DS) //DS18B20 begin change 开始获取数据并转换
{
if(DS==1)
{
dsreset(1);
delay(1);
tmpwritebyte(0xcc,1); // address all drivers on bus 写跳过读ROM指令
tmpwritebyte(0x44,1);
} // initiates a single temperature conversion 写温度转换指令
if(DS==2)
{
dsreset(2);
delay(1);
tmpwritebyte(0xcc,2); // address all drivers on bus 写跳过读ROM指令
tmpwritebyte(0x44,2);
} // initiates a single temperature conversion 写温度转换指令
}

uint tmp1(void) //get the temperature 读取寄存器中存储的温度数据
{
float tt;
uchar a,b;
dsreset(1);
delay(1);
tmpwritebyte(0xcc,1);
tmpwritebyte(0xbe,1);
a=tmpread(1); //读低8位
b=tmpread(1); //读高8位
temp1=b;
temp1<<=8; //two byte compose a int variable 两个字节组合为1个字
temp1=temp1|a;
tt=temp1*0.0625; //温度在寄存器中是12位,分辨率是0.0625
temp1=tt*10+0.5; //乘10表示小数点后只取1位,加0.5是四折五入
//temp1=temp1+5; //误差补偿
return temp1;
}
uint tmp2( void) //get the temperature 读取寄存器中存储的温度数据
{
float tt;
uchar a,b;
dsreset(2);
delay(1);
tmpwritebyte(0xcc,2);
tmpwritebyte(0xbe,2);
a=tmpread(2); //读低8位
b=tmpread(2); //读高8位
temp2=b;
temp2<<=8; //two byte compose a int variable 两个字节组合为1个字
temp2=temp2|a;
tt=temp2*0.0625; //温度在寄存器中是12位,分辨率是0.0625
temp2=tt*10+0.5; //乘10表示小数点后只取1位,加0.5是四折五入
//temp2=temp2+5; //误差补偿
return temp2;
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}

uchar display(uint temp1,uint temp2) //显示程序
{
uchar i;
A1=temp1/100;
A2=temp1%100/10;
A3=temp1%100%10;

B1=temp2/100;
B2=temp2%100/10;
B3=temp2%100%10;

trbuf[0]=A1;
trbuf[1]=A2;
trbuf[2]=A3;
trbuf[3]=B1;
trbuf[4]=B2;
trbuf[5]=B3;

dis1[3]=tab[tempL*10/100];
dis1[4]=tab[tempL*10%100/10];
dis1[6]=tab[tempL*10%100%10];

dis1[12]=tab[tempH*10/100];
dis1[13]=tab[tempH*10%100/10];
dis1[15]=tab[tempH*10%100%10];
dis2[3]=tab[A1];
dis2[4]=tab[A2];
dis2[6]=tab[A3];

dis2[12]=tab[B1];
dis2[13]=tab[B2];
dis2[15]=tab[B3];

delay(1);
lcd_pos(0); //设置显示位置为第一行的第1个字符
delay(2);
for(i=0;i<16;i++)
{
lcd_wdat(dis1[i]);
}
delay(2);
lcd_pos(0x40);
delay(2);
for(i=0;i<16;i++)
{
lcd_wdat(dis2[i]);
}

return (A1,A2,A3,B1,B2,B3);
}
void TemC()
{
if(temp1<=(tempL*10)||temp2<=(tempL*10)) tem=0;
else tem=1;
if (temp1>=(tempH*10)||temp2>=(tempH*10)) win=0;
else win=1;
}

uchar chan()
{
if(key1==0)
{
tempL++;
while(key1==0);
if(tempL>35)
tempL=0;
}

if(key2==0)
{
tempH++;
while(key2==0);
if(tempH>35)
tempH=0;
}
return (tempH,tempL);
}

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

void main()
{ //uchar a;

//uchar i;
delay(10);
lcd_init();
Init();
tempH=35;
tempL=15;
while(1)
{
tmpchange(1);
tmpchange(2);
tmp1();
tmp2();
chan();
TemC();
display(temp1,temp2);

tready=1;
rready=1;
}
}
void ssio(void)interrupt 4
{
uchar a;
RI=0;
ES=0;
if(SBUF!=SLAVE)
{
ES=1;
goto reti;
}
SM2=0;
SBUF=SLAVE;
while(TI!=1);
TI=0;
while(RI!=1);
RI=0;

if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
a=SBUF;
if(a==0x02)
{
if(tready==1)
SBUF=0x02;
else
SBUF=0x00;
while(TI!=1);
TI=0;

str();
goto reti;
}
else
{
SBUF=0x08;
while(TI!=1);
TI=0;
SM2=1;
ES=1;
}
reti:RI=0;
SM2=1;
ES=1;

}
void str(void)
{
uchar i;
tready=0;
while(1)
{

tmpchange(1);
tmpchange(2);
tmp1();
tmp2();
chan();
TemC();
display(temp1,temp2);
for(i=0;i<BN;i++)
{
SBUF=trbuf[i];
while(TI!=1);
TI=0;
}
while(RI!=1);
RI=0;
if(RB8==1)goto loop;
}
loop:SM2=1;
ES=1;
}

4. C51单片机中怎么写一个中断程序,可以用一个温度传感器来实现。当温度过高时就自动报警。

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P3^7; //define interface 定义DS18B20接口
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit p0_5=P0^5;
sbit p2_7=P2^7;
sbit p2_4=P2^4;
sbit p2_5=P2^5;
sbit p2_6=P2^6;

unsigned char code TABLE[]={
0xd7,0x11,0xcd,0x5d,0x1b,
0x5e,0xde,0x15,0xdf,0x5f,
0x9f,0xdf,0xc6,0xd7,0xce,0x8e};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i; //DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit 读一位
{
uint i;
bit dat;
DS=0;i++; //i++ for delay 小延时一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好
//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{ //写一个字节到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0 写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}

void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset(); //初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
uint tmp() //get the temperature 获得温度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a; //两字节合成一个整型变量。
tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
return temp; //返回温度值
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp)
{
uchar a,b,c,d;
a=temp/100;
b=temp/10-a*10;
d=temp%10;
c=(temp%100-d)/10;

P0=TABLE[d];
p0_5=0;
p2_7=0;
delay(1);
p2_7=1;

P0=TABLE[c];
p2_4=0;
delay(1);
p2_4=1;

P0=TABLE[b];
p0_5=1;
p2_5=0;
delay(1);
p2_5=1;

P0=TABLE[a];
p2_6=0;
delay(1);
p2_6=1;
}

void main() //主函数
{
uchar a;
Init_Com(); //初始化串口
do
{
tmpchange(); //温度转换
for(a=10;a>0;a--)
{
display(tmp()); //显示十次
}
}
while(1);
}

5. 用单片机设计制作一个模拟的十字路口交通信号灯控制系统。

摘 要

在日常生活中,交通信号灯的使用,使交通得以有效管理,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果。交通灯控制系统由80C51单片机、键盘、LED显示、交通灯延时组成。系统除具有基本交通灯功能外,还具有时间设置、LED信息显示功能,市交通实现有效控制。

关键字:交通灯;单片机;自动控制;LED

Abstract

In daily life, the use of traffic lights, so traffic can be managed effectively in smoothing traffic flow, increase road capacity and rece traffic accidents have remarkable results. Traffic light control system consists of 80C51 microcontroller, keypad, LED display, traffic light delay component. In addition to the traffic light system has the basic functions, but also with time settings, LED information display function, achieving effective control of city traffic

Key Words:traffic lights; SCM; control; LED

目 录

1 交通灯任务、功能要求说明及总体方案介绍 …………………………………1
1.1 交通灯任务…………………………………………………………………1
1.2 功能要求说明………………………………………………………………1
1.3 设计总体方案介绍及工作原理说明………………………………………2
2 交通灯硬件系统的设计 …………………………………………………………4
2.1 硬件系统各模块功能介绍…………………………………………………4
2.2 电路原理图 ………………………………………………………………5
2.3 电路PCB图 ………………………………………………………………5
2.4 元器件布局图 ……………………………………………………………5
2.5 元器件清单 ………………………………………………………………5
3 交通灯软件系统的设计 …………………………………………………………7
3.1 单片机的使用资源情况 …………………………………………………7
3.2 软件模块功能介绍 ………………………………………………………8
3.3 程序流程图 ………………………………………………………………8
3.4 程序清单 …………………………………………………………………10
4 设计总结…………………………………………………………………………11
4.1 使用说明 …………………………………………………………………11
4.2 误差分析 …………………………………………………………………11
4.3 设计体会 …………………………………………………………………11
4.4 教学建议 …………………………………………………………………12
参考文献 ……………………………………………………………………………13
致 谢 ………………………………………………………………………………14
附录一 电路原理图 ………………………………………………………………15
附录二 电路PCB顶层图 …………………………………………………………16
附录三 电路PCB底层图 …………………………………………………………17
附录四 元器件布局图 ……………………………………………………………18
附录五 元器件清单 ………………………………………………………………19
附录六 程序清单…………………………………………………………………20
1 交通灯任务、功能要求说明及总体方案介绍

1.1 交通灯任务
设计一个具有特定功能的十字路口交通灯。该交通灯上电或按键复位后能自动显示系统提示符“P.”, 进入准备工作状态。按开始键则开始工作,按结束键则返回“P.”状态。要求甲车道和乙车道两条交叉道路上的车辆交替运行,甲车道为主车道,每次通车时间为60秒,乙车道为次车道,每次通车时间为30秒,要求黄灯亮3秒,并且1秒闪烁一次。有应急车辆出现时,红灯全亮,应急车辆通车时间10秒,同时禁止其他车辆通过。
1.2 功能要求说明
本次课程设计在硬件方面的接法如下:P2口接二极管,P2.0、P2.1、P2.2口线分别来控制东西方向的绿灯、黄灯和红灯;P2.3、P2.4、P2.5口线分别控制南北方向的红灯、黄灯和绿灯。P0口作为数码管的位控(这里只用到了P0.0、和P0.1两根口线),P1口作为数码管的段控,P3口作为输入部分(这里用到了P3.0、P3.1、P3.2口线),控制数码管的显示情况和二极管的亮灭情况。
当交通灯上电或按键复位后能自动显示系统提示符“P.”,进入准备工作状态。
当按下启动按钮K1并释放后,数码管显示将会从“60”开始倒计时,每隔一秒减1,此时南北方向开始一直亮绿灯,东西方向一直亮红灯,直到显示为“00”时,数码管将会从“03”开始倒计时,每隔一秒减1,此时南北方向每隔一秒黄灯就闪烁一次,东西方向亮一直红灯,直到显示为“00”时,数码管将会从“30”开始倒计时,此时南北方向一直亮红灯,东西方向一直亮绿灯,直到显示为“00”时,数码管又将从“03”开始倒计时,此时南北方向一直亮红灯,东西方向每隔一秒黄灯就闪烁一次;当没有其他键按下时,交通灯将这样一直循环下去。
当按下结束键K2并释放后,数码管将显示“P.”,东西南北方向无灯亮。
当按下紧急键K3并释放后,数码管将显示“09”,并且每隔一秒就减1,
东西南北方向全部红灯亮。
单片机采用AT89S52,fosc=12MHZ。其按键功能如表1.1所示。

表1.1 按键功能
按键 键名 功能
P3.4 K1键 启动键
P3.7 K2键 结束键
P3.6 K3键 紧急键
1.3 设计总体方案介绍及工作原理说明
1.3.1 总体方案介绍
该交通灯电路由单片机AT98S52、键盘接口电路、显示接口电路、发光二极管控制电路、时钟电路和复位电路构成,原理框图如图1.1所示。
图1.1 原理框图
(1) 电源提供方面
采用独立的稳压电源,此方案的优点是稳定可靠,且有各种成熟电路可供使用。
(2) 显示方面
完全采用数码管显示,用来显示有限符号和数码字符。
(3) 键盘输入方面
直接在I/O口线上接按键开关,因为设计时精简和优化了电路,所以剩余的口资源还比较多。我们共用到了4个按键,分别为:K0、K1、K2、K3。
1.3.2 工作原理
首先时钟电路产生单片机工作时所需要的时钟信号,这是单片机能够正常工作的前提,而单片机有无定时的基础以及定多长的时间,这些还需要我们人为的确定。我是采用10ms延时程序来反复调用来定时,在我们的硬件电路中,按键的键功能程序在中断服务中,在正常情况下会不断运行主程序,当有键按下时,CPU去转去执行中断程序,而中断程序可以执行三种键功能:第一个是十秒倒计时紧急红灯亮;第二个是结束倒计时,显示P.;第三个是重新开始倒计时。其原理是INTO=P3.4&P3.6&P3.7,当有键按下时,外部中断0口线就会变成低电平,通过键扫程序来具体判断到底是哪个键按下,CPU才会去执行中断里面的某个键功能。12个发光二极管是由P0口控制的,P0口与二极管之间串接一个限流电阻使二极管不易烧坏,采用送低电平有效。

2 交通灯硬件系统的设计

2.1 硬件系统各模块功能介绍
2.1.1 显示电路
在本次课程设计中,我们采用的是四位一体共阳数码管。本设计的显示驱动是采用三极管作为驱动。并且,无论是位控线上还是段控线上都串接一个电阻,以提高其输出功率,在这里采用220欧母电阻。
2.1.2 指示灯控制电路
本次课程设计采用P3口控制二极管的发光情况,口线送低电平有效,具体设计如下:P3.2控制东西方向的绿灯,P3.4口控制东西方向的黄灯,P3.5控制东西方向的红灯,P3.1控制南北方向的红灯,P3.7控制南北方向的黄灯,P3.0控制南北方向的绿灯。
2.1.3 键盘控制电路
键盘是最常用的输入设备,是实现人机对话的纽带。按其结构形式可分为非编码键盘和编码键盘。
编码键盘采用硬件方法产生键码。每按下一个键,键盘能自动生成键盘代码,键数较多,且具有去抖动功能。这种键盘使用方便,但硬件较复杂。非编码键盘仅提供按键开关工作状态,其键码由软件确定,这种键盘键数较少,硬件简单,广泛应用于各种单片机应用系统,在单片机控制电路中,可把单片机使用的键盘分为独立式和矩阵式两种。独立式实际上就是一组独立的按键,这些按键可直接与单片机的I/O口连接,即每个按键独占一条口线,这种接法简单。矩阵式键盘也称行列式键盘,因为键的数目较多,所以键按行列组成矩阵。本设计中键盘数目较少,且为安装方便,因此在本设计中采用独立式接法。
按从一个键到键的功能被执行主要应包括两项工作:一是键的识别,即在键盘中找出被按的是哪个键,另一项是键功能的实现。第一项工作是使用接口电路实现的,而第二项工作则是通过执行中断服务程序来完成。具体来说,键盘接口应完成以下操作功能:
(1) 键盘扫描,以判定是否有键被按下(称之为“闭合键”)。
(2) 键识别,以确定闭合键的行列位置。
(3) 产生闭合键的键码。
(4) 排除多键、串键(复键)及去抖动。
以上这些内容通常是以软硬件结合的方式来完成的,即在软件的配合下由接口电路来完成。但具体哪些由硬件哪些由软件完成,要看接口电路的情况。总的原则是,硬件复杂软件就简单,硬件简单软件就得复杂一些。
2.1.4 时钟电路
时钟电路用来产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地按时序进行工作。通过在芯片的外部XTAL1和XTAL2两个引脚跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡电路。时钟电路为单片机产生时钟脉冲序列,本设计中采用的晶振频率为12MHz,电容为33pF。
2.1.5 复位电路
复位电路用于产生复位信号,通过RST引脚送入单片机,复位是单片机的初始操作,其主要功能是:为一些专用寄存器设置初始状态、程序状态字PSW清0、程序计数器PC被赋值为0000H等,除了进入系统的正常初始化之外,当由于程序运行出错或操作错误使系统处于死锁状态时,为摆脱困境,也需安装复位键以重新启动。RST引脚是复位信号的输入端,复位信号是高电平有效,完成复位操作共需要24个状态周期,复位结束后,单片机从地址0000H单元开始执行程序,SP为07H,其它寄存器大多数被置为00H,本设计使用频率为12MHz的晶振,所以复位信号持续时间应超过2μs才能完成复位操作。复位电路分为上电复位、按键复位、按键脉冲复位三种,本次课程设计采用的是按键复位。
2.1.6 单片机最小系统
它采用单片机AT89S52芯片,能实现基本I/O口实验,定时计数器实验等等。具有单片机并口的输入、输出的功能特点。
2.2 电路原理图
电路原理图见附录一所示。
2.3 电路PCB图
电路PCB顶层图见附录二所示;
电路PCB顶层图见附录三所示。
2.4 元器件布局图
元器件布局图见附录四所示。
2.5 元器件清单
元器件清单见附录五所示。

3 交通灯软件系统的设计

3.1 单片机的使用资源情况
3.1.1 硬件资源使用说明
 P0口为二极管的控制端
 P1口用作地址/数据总线
 P2口用作地址/数据总线
 P3.4、P3.6、P3.7口线作为键盘输入端
 采用了INTO外部中断
既在AT89S52的P0口用来接十二个发光二极管的阴极,控制其亮与灭,P1口和P2口外接由2个LED数码管(LED1、LED0)构成的显示器,用P2口作LED的段码输出口(P2.0~P2.7对应于LED的a~dp),P1口作LED的位控输出线(P1.1、P1.0分别对应于LED1、LED0),其中在P1的串行口外接2个三极管作为显示驱动,显示为2个数码管(LED0~LED1)进行动态显示。P3口外接三个个按键K1、K2、K3(分别对应于P3.4、P3.7、P3.6口)用于调整显示接口电路。
3.1.2 交通灯的分配表
交通灯的口线分配如表3.1所示,“1”表示送高电平,“0”表示送低电平。
表3.1 交通灯分配表
P0.2 东西绿灯 1 1 0 1
P0.3 东西黄灯 1 1 1 0
P0.4 东西红灯 0 0 1 1
P0.5 南北红灯 1 1 0 0
P0.6 南北黄灯 1 0 1 1
P0.7 南北绿灯 0 1 1 1
控制码 6FH AFH DBH D7H

状态说明 南北放行,东西禁止 南北警告,东西禁止 南北禁止,东西放行 南北禁止,东西放行
3.2 软件模块功能介绍
主程序模块的主要任务是程序的初始化显示“P.P.”,当没任何键按下时,显示模块将一直不变,交通灯全部是熄灭的,当K0键按下并松开后开始倒计时,
其中在时间显示的过程中判断是否有K0、K1和K2键按下,当再次按下K0时,显示将重新开始倒计时,如果是K1按下,将显示“P.”,并且发光二极管全部熄灭,如果是K2按下,数码管将开始十秒倒计时,并且东西南北全部亮起红灯。
3.3 程序流程图
主程序的流程图如图3.1所示,按键判断程序流程图如图3.2所示

图3.1 主程序流程图

图3.2 判断按键程序流程图

3.4 程序清单
程序清单详见附录六 。

4 设计总结

4.1 使用说明
本实验主要是利用单片机AT89S52、数码管和发光二极管组成,整个电路结构比较简单,它能实现以下几个功能:
 时间的显示。
 红黄绿灯的发光与熄灭。
具体操作说明如下: 当交通灯上电或按键复位后能自动显示系统提示符“P.”,进入准备工作状态。当按下启动按钮K1并释放后,数码管显示将会从“60”开始倒计时,每隔一秒减1,此时南北方向开始一直亮绿灯,东西方向一直亮红灯,直到显示为“00”时,数码管将会从“03”开始倒计时,每隔一秒减1,此时南北方向没隔一秒黄灯就闪烁一次,东西方向亮一直红灯,直到显示为“00”时,数码管将会从“30”开始倒计时,此时南北方向一直亮红灯,东西方向一直亮绿灯,直到显示为“00”时,数码管又将从“03”开始倒计时,此时南北方向一直亮红灯,东西方向每隔一秒黄灯就闪烁一次;当没有其他键按下时,交通灯将这样一直循环下去。当按下结束键K2并释放后,数码管将显示“P.”,东西南北方向无灯亮,当有其它键按下时,就退出,去执行该键的键功能。当按下紧急键K3并释放后,数码管将显示“10”,并且每隔一秒就减1,东西南北方向全部红灯亮,当没亮到显示“00”就有其它键按下时,就退出,执行该键的键功能,当显示到“00”时,就会自动退出中断继续完成主程序。
4.2 误差分析
本次课程设计的误差就在于显示时间,我采用的是调用延时程序来让显示器上数字共显示一秒钟,而循环一次的时间并不仅仅只是2次调用延时程序的时间,其间CPU还执行其它指令,例如说将缓存区的内容送给累加器A、查表指令、将段控码送给P2口等等,因为它们都是微秒级的,而延时程序是毫秒级的,因此在计算的过程中就可以省略了,每次循环除两次调用延时程序外,所用时间为22微秒,而显示一秒钟共循环了50次,因此在显示器上只需要显示1秒数字,事实上多显示了1100微秒,误差率=1.1%。
4.3 设计体会
经过一个多星期的时间,终于完成了这次的课程设计。在这期间,其他同学提出了许多宝贵的意见,使这次设计终于完满成功了。
我觉得作为一名自动化专业的学生,单片机的课程设计是很有意义的。更重要的是如何把自己平时所学的东西应用到实际中。虽然自己对于这门课懂的并不多,很多基础的东西都还没有很好的掌握,觉得很难,也没有很有效的办法通过自身去理解,但是靠着这一个多礼拜的“学习”,在同学的帮助和讲解下,渐渐对这门课逐渐产生了些许的兴趣,自己开始主动学习并逐步从基础慢慢开始弄懂它。我认为这个收获应该说是相当大的。
经过这次课程设计,也让我更加深刻的认识到学好单片机的重要意义。当今单片机渗透到我们生活的各个领域比如从导弹的导航装置、飞机上各种仪表的控制、计算机的网络通讯与数据传输、自动控制领域的机器人、智能仪表、医疗器械、工业自动化过程的实时控制和数据处理等等到我们生活中接触到的各种智能IC卡、民用豪华轿车的安全保障系统、录像机、摄像机、全自动洗衣机的控制以及程控玩具、电子宠物等等,这些都离不开单片机。它主要是作为控制部分的核心部件。因此,单片机的学习、开发在各行各业异常重要。在今后的学习中,我会更加努力的学习巩固单片机,为以后的工作打下坚固的基础。
4.4 教学建议
在王韧老师的严格要求与耐心指导下,经过一个学期对单片机技术这门课程的学习,使我对单片机这一技术的应用有了一定的了解,并对单片机的学习产生了浓厚的兴趣。
通过本次单片机控制交通灯的设计,结合本人的学习过程与切身感受向老师提出以下几点教学意见:希望老师以后能够在一开始教这门课的时候就让整个班分好小组,让那些对单片机比较熟悉的同学帮助基础较差的同学,那样可以提高学习的效率与热情;另外,王老师可以多介绍些与单片机相关的资料书给学生,培养学生查阅资料书的能力;最后一点,就是王老师在单片机扩展方面不必讲解的过细,重点在于引导思路,形成单片机的整体框架结构。

附录一 电路原理图

附录二 PCB顶层图

附录三 PCB底层图

附录四 元器件布局图

附录五 交通灯元器件清单

元器件及材料名称 规格 数目 备注
AT89S52加底座 1
四位一体共阳数码管加底座 2 0.5寸
晶振 12MHz 1 三晶
发光二极管 大个的 9
单排插 40脚 1
三极管 9012 9
蜂鸣器 1 5V
小按键 9 6*6*4.3mm
下载口座子 十芯 1 FC-10P
18b20温度传感器 1
六脚按键开关 1 6*6*4.3mm
Usb电源线加接口 1 USB线加USB接口
电阻 200 1
电阻 4.7K 1
电阻 1K 3
电阻 470 24
电解电容 22uf 1
瓷片电容 33pf 2
排阻 10k 2
短路帽 3
杜邦线8P 1
PCB板子 150mm*200mm 1
电源白色插座 1

附录六 程序清单

ORG 0000H
LJMP MAIN
ORG 001BH
LJMP LOOP1
ORG 0030H
MAIN: MOV PSW, #00H; 初始化
MOV SP, #7FH
MOV TMOD, #10H;
MOV TH1, #3CH;
MOV TL1, #0B0H;
MOV TH0, #0FCH;
MOV TL0, #18H;
MOV 78H, #11H;
MOV 79H, #10H;
MOV 7AH, #10H;
MOV 7BH, #10H;
MOV 7CH, #10H;
MOV 7DH, #10H;
MOV 7EH, #10H;
MOV 7FH, #10H;
MOV R7, #0FAH;
MOV R6, #32H;
MOV R5, #05H;
MOV R4, #39H;
MOV R1, #20;
SETB EA;
SETB ET1;
PP: LCALL DIR;
START: LCALL KEY;
JB 20H.0, K0;
LJMP PP;
K0: MOV R4, #39H;
MOV R1, #20;
SETB TR1;
MOV 78H, #07H;
MOV 79H, #05H;
MOV 7AH, #10H;
MOV 7BH, #10H;
MOV 7CH, #10H;
MOV 7DH, #10H;
MOV 7EH, #10H;
MOV 7FH, #10H;
LCALL DIR;
CYCLE0: MOV P3, #0DEH;主绿副红
JB 20H.2, OUT;
KK0: JB 20H.1, JINJI;

CJNE R4, #00, CYCLE0;延时60秒
MOV R4, #03H;

MOV 78H, #03H;
MOV 79H, #00H;
CYCLE1: MOV P3, #0DFH;
JB 20H.2, OUT;
JB 20H.1, JINJI;
CJNE R1, #10, CYCLE1;
CYCLE2: MOV P3, #0DDH;
JB 20H.2, OUT;
JB 20H.1, JINJI;
CJNE R1, #20, CYCLE2;
CJNE R4, #00H, CYCLE1;
MOV R4, #1EH;

MOV 78H, #07H;
MOV 79H, #02H;
CYCLE3: MOV P3, #0F3H;主红副绿
JB 20H.2, OUT;
JB 20H.1, JINJI;
CJNE R4, #00, CYCLE3;延时30秒
MOV R4, #03H;

MOV 78H, #03H;
MOV 79H, #00H;
CYCLE4: MOV P3, #0DFH;
JB 20H.2, OUT;
JB 20H.1, JINJI;
CJNE R1, #10, CYCLE4;
CYCLE5: MOV P3, #0DDH;
JB 20H.2, OUT;
JB 20H.1, JINJI;
CJNE R1, #20, CYCLE5;
CJNE R4, #00H, CYCLE4;
MOV R4, #39H;
LJMP K0;

JINJI: MOV R4, #10;紧急车辆按键
CYCLE6: MOV P3, #0DBH
CJNE R4, #00, CYCLE6;
LJMP K0;

OUT: MOV P3, #0FFH;
MOV 78H, #11H;
MOV 79H, #10H;
MOV 7AH, #10H;
MOV 7BH, #10H;
MOV 7CH, #10H;
MOV 7DH, #10H;
MOV 7EH, #10H;
MOV 7FH, #10H;
MOV R7, #0FAH;
LJMP PP;

DIR: PUSH DPH; 显示子程序
PUSH DPL;
PUSH ACC;
PUSH PSW;
SETB RS0;
CLR RS1;
MOV R0, #78H;
MOV R3, #0FEH;
MOV A, R3;
LD0: MOV P2, A;
MOV DPTR, #TABLE;
MOV A, @R0;
MOVC A, @A+DPTR;
MOV P0, A;
LCALL DELAY;
INC R0;
MOV A, R3;
JB ACC.7, LD1;
RL A;
MOV R3, A;
LJMP LD0;
LD1: CLR RS0; 恢复当前通用寄存器组组号
CLR RS1;
POP PSW;
POP ACC; 恢复现场
POP DPL;
POP DPH;
RET;

TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H; 0--6
DB 0F8H,80H,90H,88H,83H,0C6H,0A1H; 7--D
DB 86H,8EH,0FFH,0CH; E--F,灭,P.

KEY: LCALL KEYCHULI;键扫程序
JZ EXIT;
LCALL XX0;
LCALL KEYCHULI
JZ EXIT;
MOV B, 20H;
KEYSF: LCALL KEYCHULI;
JZ KEY1;
LCALL XX0;
LJMP KEYSF;
KEY1: MOV 20H, B;
EXIT: RET;

KEYCHULI: MOV P1, #0FFH;
MOV A, P1;
CPL A;
ANL A, #0FH;
MOV 20H, A;
RET;

DELAY: DJNZ R7, DELAY;显示延时子程序
MOV R7, #0FAH;
DJNZ R5, DELAY;
MOV R5, #05H;
RET;

; 定时1秒中断程序:
LOOP1:
MOV TH1, #3CH;定时器0赋初值,定时50ms
MOV TL1, #0B0H;
LCALL DIR;
LCALL KEY;
DJNZ R1, RETURN;
DEC R4;
MOV R1, #20;
MOV R0, #79H;
LCALL DADD1;
RETURN: RETI;

; 去抖延时子程序:
XX0: DJNZ R7, XX0;
MOV R7, #0FAH;
DJNZ R6, XX0;
MOV R6, #32H;
RET;

减一子程序:
DADD1: MOV A, @R0;
DEC R0;
SWAP A;
ORL A, @R0;
SUBB A, #01H;
DA A;
MOV R2, A;
ANL A, #0FH;
MOV @R0, A;
MOV A, R2;
INC R0;
ANL A, #0F0H;
SWAP A;
MOV @R0, A;
RET;

END

6. 单片机中的看门狗是什么东西,有什么作用

看门狗(WDT)是一个定时器。看门狗是用来防止万一单片机程序出错造成重大损失的。防错的原理很简单,它在硬件上就是一个定时器,当它溢出的时候就会让单片机强制复位使程序重新开始执行。

正常的情况下是不能让它溢出的,所以在程序上每隔一段时间要给他置一次值(俗称喂狗),只要程序中正常给它喂他就不会溢出。

一旦程序跑飞了,有干扰或者进入死循环之类的情况时,不能正常执行程序了,那么就永远执行不到喂狗的指令了,但此时定时器是硬件控制的,仍然会走,所以溢出了,单片机就复位了。

一般安全性要求比较高的,系统跑飞了会造成重大事故的都会加一个“狗”保安全。

通常,看门狗的溢出时间越短越灵敏,跑飞之后复位的时间越短,也就越安全,但是,喂狗的操作也要更频繁。

(6)单片机ofe扩展阅读:

看门狗工作原理:

使用时,WDT将递增直到溢出或“超时”。 除非处于休眠或空闲模式,否则WDT超时将强制器件复位。 为避免WDT超时复位,用户必须使用PWRSAV或CLRWDT指令定期清除看门狗定时器。 如果WDT在休眠或空闲模式下超时。

器件将唤醒并从执行PWRSAV指令的位置继续执行代码。 在以上两种情况下,WDTO位(RCON <4>)将被置1,表明器件复位或唤醒事件是由WDT超时引起的。

如果WDT将CPU从睡眠或空闲模式唤醒,则还将置位“睡眠”状态位(RCON <3>)或“空闲”状态位(RCON <2>),表明该设备先前已上电。 保存模式。

在正常操作期间,WDT超时将产生设备复位。 当设备处于睡眠状态时,WDT超时将唤醒设备以继续正常操作(称为WDT唤醒)。 清零WDTE设置位可以永久关闭WDT。 后分频器分配完全由软件控制,也就是说,可以在程序执行期间随时更改它。

为避免不可预测的器件复位,当从Timer0预分频器分配更改为WDT后分频器分配时,必须执行以下指令序列。 即使禁止了WDT,也必须执行该指令序列。

7. 基于51单片机的温度控制器

图片为温度控制电路图。温度到达上限时led灯亮,并停止对RT的加热,温度达到下限时led灯灭并开始对RT进行加热。A1和A2为uA741运算放大器。引脚号在图上已经标出。再给你一个单片机采集DS18B20温度的程序,用四位数码管显示的。你把DS18B20接在RT附近就可以测试出RT的温度,调节图中的滑动变阻器可改变温度的上下限。这样就能做到温度控制了。

//安装目录下的EXE文件打开后可在电脑上显示当前温度值

#include<reg52.h>

#defineucharunsignedchar

#defineuintunsignedint

sbitDS=P1^0;//defineinterface

uinttemp;//variableoftemperature

ucharflag1;//

//sbitla=P2^6;

//sbitwela=P2^7;

//unsignedcharcodetable2[]={0x3f,0x30,0x5b,0x4f,0x66,0x6d,0x7d,

//0x07,0x7f,0x67/*,0x77,0x7c,0x39,0x5e,0x79,0x71*/};

//unsignedcharcodetable1[]={0xbf,0xb0,0xdb,0xcf,0xe6,0xed,0xfd,

//0x87,0xff,0xe7};

//unsignedcharcodetable2[]={0x40,0x5e,0x24,0x21,0x13,0x09,0x08,

//0x63,0x00,0x03/*,0x77,0x7c,0x39,0x5e,0x79,0x71*/};

//unsignedcharcodetable1[]={0xc0,0xde,0xa4,0xa1,0x93,0x89,0x88,

//0xe7,0x8f,0x87};

unsignedcharcodetable5[]={0x77,0x22,0x6d,0x5d,0x1e,0x5b,0x7b,

0x15,0x7f,0x1f};

unsignedcharcodetable6[]={0xf7,0xa2,0xed,0xdd,0x9e,0xdb,0xfb,

0x95,0xff,0x9f};

voiddelay(uintcount)//delay

{

uinti;

while(count)

{

i=200;

while(i>0)

i--;

count--;

}

}

///////功能:串口初始化,波特率9600,方式1///////

voidInit_Com(void)

{

TMOD=0x20;

PCON=0x00;

SCON=0x50;

TH1=0xFd;

TL1=0xFd;

TR1=1;

}

voiddsreset(void)//复位,初始化函数

{

uinti;

DS=0;

i=103;

while(i>0)i--;

DS=1;

i=4;

while(i>0)i--;

}

bittmpreadbit(void)//readabit读1位数据函数

{

uinti;

bitdat;

DS=0;i++;//i++fordelay

DS=1;i++;i++;

dat=DS;

i=8;while(i>0)i--;

return(dat);

}

uchartmpread(void)//readabytedate读1字节函数

{

uchari,j,dat;

dat=0;

for(i=1;i<=8;i++)

{

j=tmpreadbit();

dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

return(dat);

}

voidtmpwritebyte(uchardat)//writeabytetods18b20向1820写一个字节数据函数

{

uinti;

ucharj;

bittestb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(testb)//write1

{

DS=0;

i++;i++;

DS=1;

i=8;while(i>0)i--;

}

else

{

DS=0;//write0

i=8;while(i>0)i--;

DS=1;

i++;i++;

}

}

}

voidtmpchange(void)//DS18B20beginchange开始获取数据并转换

{

dsreset();

delay(1);

tmpwritebyte(0xcc);//addressalldriversonbus写跳过读ROM指令

tmpwritebyte(0x44);//写温度转换指令

}

uinttmp()//getthetemperature读取寄存器中存储的温度数据

{

floattt;

uchara,b;

dsreset();

delay(1);

tmpwritebyte(0xcc);

tmpwritebyte(0xbe);

a=tmpread();//读低8位

b=tmpread();//读高8位

temp=b;

temp<<=8;//twobytecomposeaintvariable两个字节组合为1个字

temp=temp|a;

tt=temp*0.0625;//温度在寄存器中是12位,分辨率是0.0625

temp=tt*10+0.5;//乘10表示小数点后只取1位,加0.5是四折五入

returntemp;

}

voidreadrom()//readtheserial

{

ucharsn1,sn2;

dsreset();

delay(1);

tmpwritebyte(0x33);

sn1=tmpread();

sn2=tmpread();

}

voiddelay10ms()//delay

{

uchara,b;

for(a=10;a>0;a--)

for(b=60;b>0;b--);

}

voiddisplay(uinttemp) //显示程序

{

ucharA1,A2,A2t,A3,ser;

ser=temp/10;

SBUF=ser;

A1=temp/100;

A2t=temp%100;

A2=A2t/10;

A3=A2t%10;

//la=0;

d4=0;

P0=table5[A1];

delay(1);

d4=1; //显示百位

//la=1;

//la=0;

/*wela=0;

P0=0x7e;

wela=1;

wela=0; */

//la=0;

d3=0;

P0=table6[A2];

delay(1);

d3=1; //显示十位

//la=1;

//la=0;

/*wela=0;

P0=0x7d;

wela=1;

wela=0; */

d2=0;

P0=table5[A3];

delay(1);

d2=1; //显示个位

//la=1;

//la=0;

/*P0=0x7b;

wela=1;

wela=0; */

}

voidmain()

{

uchara;

Init_Com();

do

{

tmpchange();

//delay(200);

for(a=1;a>0;a--)

{display(tmp());

}

}while(1);

}

8. 求《单片机温度测量系统设计》的相关资料!

要:本文介绍了一种基于MSP430 单片机的温度测控装置。该装置可实现对温度的测量,并能根据设定值对环境温度进行调节,实现控温的目的。控制算法基于数字PID算法。

0 引言
温度是工业控制中主要的被控参数之一,特别是在冶金、化工、建材、食品、机械、石油等工业中,具有举足重轻的作用。随着电子技术和微型计算机的迅速发展,微机测量和控制技术得到了迅速的发展和广泛的应用[1]。单片机具有处理能强、运行速度快、功耗低等优点,应用在温度测量与控制方面,控制简单方便,测量范围广,精度较高。
本文设计了一种基于MSP430单片机的温度测量和控制装置,能对环境温度进行测量,并能根据温度给定值给出调节量,控制执行机构,实现调节环境温度的目的。

1 整体方案设计
单片机温度控制系统是以MSP430单片机为控制核心。整个系统硬件部分包括温度检测系统、信号放大系统、A/D转换、单片机、I/O设备、控制执行系统等。
单片机温度控制系统控制框图如下所示:

温度传感器将温度信息变换为模拟电压信号后,将电压信号放大到单片机可以处理的范围内,经过低通滤波,滤掉干扰信号送入单片机。在单片机中对信号进行采样,为进一步提高测量精度,采样后对信号再进行数字滤波。单片机将检测到的温度信息与设定值进行比较,如果不相符,数字调节程序根据给定值与测得值的差值按PID控制算法设计控制量,触发程序根据控制量控制执行单元。如果检测值高于设定值,则启动制冷系统,降低环境温度;如果检测值低于设定值,则启动加热系统,提高环境温度,达到控制温度的目的。

2 温度信号检测
本系统中对检测精度要求不是很高,室温下即可,所以选用高精度热敏电阻作为温度传感器。热敏电阻具有灵敏度较高、稳定性强、互换精度高的特点。可使放大器电路极为简单, 又免去了互换补偿的麻烦。
热敏电阻具有负的电阻温度特性,当温度升高时,电阻值减小,它的阻值—温度特性曲线是一条指数曲线,非线性度较大。而对于本设计,因为温度要求不高,是在室温环境下,热敏电阻的阻值与环境温度基本呈线性关系[2],这样可以通过电阻分压简单地将温度值转化为电压值。
给热敏电阻通以恒定的电流,可得到电阻两端的电压,根据与热敏电阻特性有关的温度参数T0 以及特性系数k,可得下式
T=T0-kV(t) (1)
式中T为被测温度。
根据上式,可以把电阻值随温度的变化关系转化为电压值随温度变化的关系,由于热敏电阻的电信号一般都是毫伏级,必须经过放大,将热敏电阻测量到的电信号转化为0~3.6之间,才能在单片机中使用。
下图为放大电路原理图。稳压管的稳压值为1.5V。

由于传感器输出微弱的模拟信号,当信号中存在环境干扰时,干扰信号也被同时放大,影响检测的精度,需用滤波电路对先对模拟信号进行处理,以提高信号的抗干扰能力。本系统采用巴特沃斯二阶有源低通滤波电路。选取该巴特沃斯二阶有源低通滤波电路的截止频率
fH=10 kHz 。

3 控制系统设计
3.0 软件设计
单片机温度控制器控制温度范围100℃到400℃,采用通断控制,通过改变给定控制周期内加热和制冷设备的导通和关断时间,来提高和降低温度,以达到调节温度的目的。
软件设计中选取控制周期TC 为200(T1×C) ,导通时间取Pn ×T1×C ,其中Pn 为输出的控制量,Pn值介于0~200之间, T1 为定时器定时的时间,C为常数。由上两式可看出,通过改变T1 定时时间或常数C,就可改变控制周期TC 的大小。温度控制器控制的最高温度为400℃,当给定温度超过400℃时以400℃计算。
图3为采样中断流程图。

数模转换部分使用单片机自带的12位A/D转换器,能同时实现数模转换和控制,免去使用专用的转换芯片,使系统处理速度更快,精度更高,使电路简化。采样周期为500 μs ,当采集完16个点的数据以后,设置标志“nADCFlag =1”,通知主程序采集完16个点的数据,主程序从全局缓冲区里读出数据。
为进一步减小随机信号对系统精度的影响,A/D转换后,用平均值法对采样值进行数字滤波。每16个采样点取一次平均值。然后将计算到的平均值作为测量数据进行显示。同时,按照PID算法,对温度采样值和给定值之间的偏差进行控制,得到控制量。采样全过程完成后就可屏蔽采样中断,同时启动T1定时[3],进入控制过程。
温度值和热敏电阻的测量值在整个温度采样区间内基本呈线性变化,因此在程序中不需要对测量数据进行线性校正。MSP430的T1定时器中断作为控制中断,温度采样过程和控制输出过程采用了互锁结构,即在进行温度采样,温度值处理和运算等过程时T1不定时,待采样全过程进行完时再启动T1定时并同时屏蔽采样中断。T1定时开始就进入控制过程,在整个控制过程中都不采样,直到200(T1×C) 定时时间到,要开始新一轮的控制周期。在启动采样的同时屏蔽T1中断。
图4为T1定时中断流程图。

图中,M代表定时器控制周期计数值,N则表示由调节器计算出的控制量。首先判断控制周期TC是否己经结束。若控制周期TC已结束(即M=0),则屏蔽T1定时器中断,进行新一轮温度采样;若控制周期TC还未结束〔即M≠0 〕,则开始判断导通时间是否结束。若导通时间己结束(即N=0),则置输出控制信号为低,并重新赋常数C值,启动定时器定时,同时退出中断服务程序;若导通时间还未结束(即N ≠0 ),则置输出控制信号为高,控制执行其间继续导通,重新赋常数C值,启动定时器定时,同时退出中断服务程序。

3.1 数字PID
本文控制算法采用数字PID 控制,数字PID 算法表达式如下所示:

其中,KP 为比例系数;KI=KPT/TI 为积分系数;T 为采样周期,TI 为积分时间系数;KD=KPTD/T 为微分系数,TD 为微分时间系数。u(k) 为调节器第k次输出, e(k) 为第k 次给定与反馈偏差。
对于PID 调节器,当偏差值输出较大时,输出值会很大,可能导致系统不稳定,所以在实际中,需要对调节器的输出限幅[4],即当|u|>umax 时,令u=umax 或u=-umax ,或根据具体情况确定。

3.2 温度调节
PI 控制器根据温度给定值和测量值之间的偏差调节,给出调节量,再通过单片机输出PWM 波,调节可控硅的触发相位的相位角,以此来控制执行部件的关断和开启时间,达到使温度升高或降低的目的。随后整个系统再通过检测前一阶段控制后的温度,进行近一步的控制修正,最终实现预期的温度监控目的。

4 结论
本设计利用单片机低功耗、处理能力强的特点,使用单片机作为主控制器,对室内环境温度进行监控。其结构简单、可靠性较高,具有一定的实用价值和发展前景。

参考文献
[1] 赵丽娟,邵欣.基于单片机的温度监控系统的设计与实现.机械制造,2006,44(1)
[2] 张开生,郭国法.MCS-51 单片机温度控制系统的设计.微计算机信息,2005,(7)
[3] 沈建华,杨艳琴,翟骁曙..MSP430 系列16 位超低功耗单片机原理与应用.清华大学出版社,2004,148-155
[4] 赖寿宏.微型计算机控制技术.北京:机械工业出版社,1994:90-95

阅读全文

与单片机ofe相关的资料

热点内容
合肥高铁买票有什么app嘛 浏览:653
压缩机电容原理 浏览:758
单片机对微电子技术的影响 浏览:474
phptts 浏览:818
程序员有写代码吗 浏览:677
系列数乘积算法 浏览:796
代码编程注意事项 浏览:388
材料力学刘鸿文第五版pdf 浏览:420
云服务器容易崩溃吗 浏览:929
广州的程序员在哪里上班 浏览:55
一带一路pdf 浏览:11
倒扣19个点算法 浏览:709
paperwhitepdf 浏览:148
全款解压的车能要不 浏览:767
设计模式之禅pdf 浏览:292
女程序员转行学什么好 浏览:741
部队退伍程序员 浏览:323
模拟时钟python 浏览:451
饥荒服务器如何变流畅 浏览:704
微信电脑版不能连接到服务器地址 浏览:355