最近新做了LM35仿真溫度電路設計加上LM358十倍放大!!
電路原理圖如下:
024.PNG (38.13 KB, 下載次數: 103)
下載附件
仿真截圖
2018-12-28 11:53 上傳
下邊是單片機代碼!!!第一次發帖
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//===========================
//ADC0809相關引腳定義
//===========================
#define ADC_DATA P1
sbit ADC_EOC = P3^3;
sbit ADC_CLK = P3^4;
sbit ADC_START = P3^6;
sbit ADC_OE = P3^7;
//===========================
//4位共陽數碼管相關
//===========================
uchar code seg[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 }; //0~9 小數點不亮
uchar code seg_dot[10]={ 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10 }; //0~9 小數點亮
#define SEG_DATA P2 //數碼管段選碼,共陽數碼管,低電平選通段選碼
sbit SEG_SEL_0 = P0^3; //數碼管位選:第0位,共陽數碼管,高電平選通位選碼
sbit SEG_SEL_1 = P0^2; //數碼管位選:第1位
sbit SEG_SEL_2 = P0^1; //數碼管位選:第2位
sbit SEG_SEL_3 = P0^0; //數碼管位選:第3位
//===========================
//警報:LED與蜂鳴器引腳
//===========================
sbit LED = P0^5; //低電平亮
sbit BEEP = P0^4; //高電平響
#define LED_ON LED=0
#define LED_OFF LED=1
#define BEEP_ON BEEP=1
#define BEEP_OFF BEEP = 0
//===========================
//粗略延時函數 AT89C51 & 12MHz
//===========================
void delayms(unsigned int ms)
{
unsigned char a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/*
//===========================
//粗略延時函數 STC12C5A60S2 & 12MHz
//===========================
void delayms(unsigned int ms)
{
unsigned char a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=222;b>0;b--)
for(a=12;a>0;a--);
}
}
*/
//===========================
//定時器初始化,配置ADC0809時鐘
//===========================
void timer_init(void)
{
//配置定時器0
ET0 = 1;
TMOD &= 0xF0;
TMOD |= 0x02; //定時器0,模式2,自動重裝定時器
TH0 = 200; //自動重裝值
TL0 = 200;
TR0 = 1;
//配置定時器1
ET1 = 1;
TMOD &= 0x0F; //清除定時器1配置,不改動定時器0的配置
TMOD |= 0x10; //定時器1模式一,不改動定時器0的模式
TH1 = (65536 - 2000)/256;
TL1 = (65536 - 2000)%256;
TR1 = 1;
EA = 1;
}
//===========================
//定時器0中斷,為ADC0809提供時鐘信號
//===========================
void timer0() interrupt 1
{
ADC_CLK = ~ADC_CLK;
}
//============================
//ADC0809 轉換函數
//============================
uchar ADC0809_GET(void)
{
ADC_START = 0;
ADC_OE = 0;
ADC_START = 1;
ADC_START = 0;
while(ADC_EOC == 0);
ADC_OE = 1;
return ADC_DATA;
}
//============================
//定時器1中斷函數,用于刷新數碼管
//============================
uchar t1_flag = 0; //用于標記顯示第幾位數碼管
uchar seg0 = 0; //第0位數碼管的值
uchar seg1 = 1; //第1位數碼管的值
uchar seg2 = 2; //第2位數碼管的值
uchar seg3 = 3; //第3位數碼管的值
void timer1() interrupt 3
{
TH1 = (65536 - 2000)/256;
TL1 = (65536 - 2000)%256;
SEG_SEL_0 = 0;
SEG_SEL_1 = 0;
SEG_SEL_2 = 0;
SEG_SEL_3 = 0;
SEG_DATA = 0xff;
if(t1_flag == 0)
{
SEG_SEL_0 = 1; //選通第0位數碼管
SEG_SEL_1 = 0;
SEG_SEL_2 = 0;
SEG_SEL_3 = 0;
SEG_DATA = seg[seg0]; //顯示帶小數點的數
}
else if(t1_flag == 1)
{
SEG_DATA = seg_dot[seg1];
SEG_SEL_0 = 0;
SEG_SEL_1 = 1; //選通第1位數碼管
SEG_SEL_2 = 0;
SEG_SEL_3 = 0;
}
else if(t1_flag == 2)
{
SEG_DATA = seg[seg2];
SEG_SEL_0 = 0;
SEG_SEL_1 = 0;
SEG_SEL_2 = 1; //選通第2位數碼管
SEG_SEL_3 = 0;
}
else if(t1_flag == 3)
{
SEG_DATA = seg[seg3];
SEG_SEL_0 = 0;
SEG_SEL_1 = 0;
SEG_SEL_2 = 0;
SEG_SEL_3 = 1; //選通第3位數碼管
}
t1_flag++; //自加1
t1_flag = t1_flag%4; //讓t1_flag 在0和3之間循環
}
//============================
//顯示電壓值,輸入0~255,顯示0.000~5.000
//============================
uint print_volt(uchar num)
{
uint volt = 0;
volt = num/255.0 * 5000 + 0.5; //除255.0和除255有很大區別,除255.0會自動轉換為float型,小數才能保持,而volt/255=0,+0.5四舍五入。
seg0 = volt/1000%10;
seg1 = volt/100%10;
seg2 = volt/10%10;
seg3 = volt%10;
return volt;
}
//============================
//主函數
//============================
void main(void)
{
uchar adc_num = 0; //ADC采集到的值
uint volt = 0; //電壓值 0~5000,代表(0~5)V
timer_init(); //定時器0、定時器1初始化。
LED_OFF;
BEEP_OFF;
while(1)
{
adc_num = ADC0809_GET();
volt = print_volt(adc_num); //在數碼管上顯示電壓值,并返回一個0~5000的值,用于判斷是否要報警。
if(volt > 2500)
{
LED_ON;
BEEP_ON;
}
else
{
LED_OFF;
BEEP_OFF;
}
delayms(100);
}
}
|