📄 temp_control.c
字号:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include "char_model.h"
#define LcdCtrl_Port PORTB
#define Lcd_Res PB2
#define Lcd_A0 PB3
#define Lcd_RW PB4
#define Lcd_E1 PB5
#define Lcd_E2 PB6
#define LcdData_Port PORTC
#define TCNT0_NOH 0xfc
#define TCNT0_NOL 0xc1
uint8_t disp_buf[20];//显示缓存
uint8_t bw,sw,gw,sf,bf, led = 0,bw_s=0,sw_s=0,gw_s=0,key_enter,key_down,key_up,key_set=1;
uint16_t ADC_rel = 0;
uint8_t flag_adc = 0;
uint8_t a = 0;
uint8_t flag0 = 1;
uint16_t temp_bj;
uint8_t flag1 = 1;
uint16_t temp_h = 0;
uint16_t temp_l = 0;
uint8_t w = 0;
uint8_t TCNT2_NO = 90, OCR2_NO = 0;
//延时
void Delay(uint32_t usecond)
{
uint8_t j = 8;
uint32_t i;
for(i = 0; i < usecond; i++)
{
while(j--);
}
}
//微控制器初始化
void MCUInit(void)
{
PORTA = 0x0f;
DDRA = 0x0f;
PORTB = 0x00;
DDRB = 0xff;
PORTC = 0x00;
DDRC = 0xff;
PORTD = 0xff;
DDRD = 0xf0;
/*TCCR1A = 0x00; //定时1初始化
TCCR1B = (1 << CS12) ;//| (1 << CS10);
//TCCR0 = (1 << CS02) | (1 << CS00) ;
TIMSK = 1 << TOIE1;
//TCNT0 = TCNT0_NO;
TCNT1H = TCNT0_NOH;
TCNT1L = TCNT0_NOL;*/
}
//命令-数据发送模块
//temp:命令或数据暂存变量,m_s:指令(0)—数据(1) 信号,l_r:左屏(0)-右屏(1)-全屏(2) 选择
void LcdDataSend(uint8_t temp, uint8_t m_s, uint8_t l_r)
{
Delay(2);//不使用忙线,所以延迟2us,等待LCD空闲
if(m_s == 0) //判断是指令还是数据:0-指令,1-数据
{
cbi(LcdCtrl_Port, Lcd_A0);
}
else
{
sbi(LcdCtrl_Port, Lcd_A0);
}
if(l_r == 0) //判断屏幕:0-左屏,1-右屏,2-全屏
{
sbi(LcdCtrl_Port, Lcd_E1);
cbi(LcdCtrl_Port, Lcd_E2);
}
else if(l_r == 1)
{
cbi(LcdCtrl_Port, Lcd_E1);
sbi(LcdCtrl_Port, Lcd_E2);
}
else if(l_r == 2)
{
sbi(LcdCtrl_Port, Lcd_E1);
sbi(LcdCtrl_Port, Lcd_E2);
}
Delay(5);
LcdData_Port = temp;//送如指令或数据
Delay(5);
cbi(LcdCtrl_Port, Lcd_E1);//关闭液晶,防止干扰
cbi(LcdCtrl_Port, Lcd_E2);
}
//通用显示模块
//addr:发送代码表的地址,page:显示的页,row:显示的列
void WordSend(uint8_t addr, uint8_t page, uint8_t row, uint8_t zy)
{
uint8_t width;//字模宽度为12*12
uint8_t hig;//字模高度为2页
for(hig = 0; hig < 2; hig++)
{
LcdDataSend(page, 0, zy);
LcdDataSend(row, 0, zy);
for(width = 0; width < 12; width++)
{
if(hig < 1)
LcdDataSend(PRG_RDB(&CBYTE[addr][width]), 1, zy);
else
LcdDataSend(PRG_RDB(&CBYTE[addr][width + 12]), 1, zy);
}
page++;
}
}
//lcd初始化
void LcdInit(void)
{
cbi(LcdCtrl_Port, Lcd_Res);
Delay(1000);
sbi(LcdCtrl_Port, Lcd_Res);
cbi(LcdCtrl_Port, Lcd_RW);
LcdDataSend(0xe2, 0, 2);//reset
LcdDataSend(0xae, 0, 2);//display on/off: off
//LcdDataSend(0xc0, 0, 2);//display start line : 1
LcdDataSend(0xa4, 0, 2);//static drive on/off: off
//LcdDataSend(0x00, 0, 2);//column address set: 0
//LcdDataSend(0xb8, 0, 2);//page address set: 1
LcdDataSend(0xa9, 0, 2);//duty select: 1/32
LcdDataSend(0xa0, 0, 2);//adc select: rightward outpu
LcdDataSend(0xee, 0, 2);//read modify write: off
LcdDataSend(0xaf, 0, 2);//display on off: ON
}
//清屏
//
void LcdClear(void)
{
uint8_t temp1, temp2;
uint8_t leaf = 0xb8;
for(temp1 = 0; temp1 < 4; temp1++)
{
LcdDataSend(leaf, 0, 2);
LcdDataSend(0, 0, 2);
for(temp2 = 0; temp2 < 60; temp2++)
{
LcdDataSend(0, 1, 2);
}
leaf++;
}
Delay(1000);
}
//PWM波输出初始化
void PWM_Init(void)
{
TCCR2 = 0x6f;
OCR2 = OCR2_NO;
TCNT2 = TCNT2_NO ;
}
//ADC初始化
void ADC_Init(void)
{
ADMUX = 0x07;
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//使能AD,128分频。
}
//AD中断服务
SIGNAL(SIG_ADC)
{
uint16_t h=0,l=0;
//ADCSRA=0x00;
//ADMUX=0x00;
l = ADCL;
h = ADCH;
ADC_rel = (h<<8)+l;//读取AD数据寄存器内的数据
flag1 = 1;
}
//INT0初始化
void INT0_init(void)
{
MCUCR = 0x10;
GICR = 0x40;
}
//中断0,用来选通4路温度采集
SIGNAL(SIG_INTERRUPT0)
{
Delay(5000);
a++;
if(a == 5) a = 1;
flag0 = 1;
}
//中断1
/*SIGNAL(SIG_INTERRUPT1)
{
Delay(1800);
w++;
if(w == 3){w=1;}
flag0 = 1;
}*/
/*******************************
键盘扫描函数
********************************/
void Key_scan(void)
{
uint8_t temp0,temp1;
temp0 = PIND & 0x0f;
Delay(5);
temp1 = PIND & 0x0f;
if(temp0 == temp1);
{
//key_set = temp0&0x04;
key_up = temp0&0x08;//设定的数据增大
key_down = temp0&0x01;//设定的数据减小
key_enter = temp0&0x02;//确定键
/*if(key_set == 0)
{
//Delay(10);
a++;
if(a==5) a=1;
flag0 = 1;
}*/
if(key_down == 0)
{
//Delay(10);
if(temp_bj>0)
{temp_bj--;}
flag0 = 1;
}
if(key_up == 0)
{
//Delay(10);
if(temp_bj < 200)
{temp_bj++;}
flag0 = 1;
}
if(key_enter == 0)
{
w++;
if(w == 3){w = 1;}
flag0 = 1;
}
}
}
/*//记数器益出中断服务
SIGNAL(SIG_OVERFLOW1)
{
TCNT1H = TCNT0_NOH;
TCNT1L = TCNT0_NOL;
//TCNT0 = TCNT0_NO;
ADMUX=0x07;
ADCSRA=0xe8;//(1<<ADEN)|(1<<ADSC)(1<<ADIE)|(1<<ADATE);
}*/
//4路选通函数
void select_ways(uint8_t w)
{
switch(w)
{
case 1:
{
cbi(PORTD,PD5);
cbi(PORTD,PD6);
break;
}
case 2:
{
sbi(PORTD,PD5);
cbi(PORTD,PD6);
break;
}
case 3:
{
cbi(PORTD,PD5);
sbi(PORTD,PD6);
break;
}
case 4:
{
sbi(PORTD,PD5);
sbi(PORTD,PD6);
break;
}
default:break;
}
}
//AD值处理函数
void ADCtoBCD(uint16_t temp)
{
bw = temp/1000;
sw = (temp%1000)/100;
gw = (temp%100)/10;
sf = temp%10;
}
//设置值处理函数
void BJtoBCD(uint16_t b)
{
bw_s = b/100;
sw_s = (b%100)/10;
gw_s = b%10;
}
//enter键处理函数
void control_set(uint8_t q)
{
switch(q)
{
case 1://确认键处理函数
{
temp_h = temp_bj;
WordSend(37, 0xba, 36, 1);
WordSend(36, 0xba, 48, 1);
break;
}
case 2://重设键处理函数
{
WordSend(34, 0xba, 36, 1);
WordSend(35, 0xba, 48, 1);
temp_bj = 0;
temp_h = 0;
w = 0;
break;
}
default:break;
}
}
//灯驱动,利用A口驱动4个发光二极管
void leddis(uint8_t a)
{
switch(a)
{
case 1: PORTA = 0x0e;break;
case 2: PORTA = 0x0d;break;
case 3: PORTA = 0x0b;break;
case 4: PORTA = 0x07;break;
//case 5: PORTA &= ~(1<<4);break;
default:break;
}
}
//显示函数
void disp(uint8_t i)
{
if(i == 0)//显示欢迎界面
{
WordSend(26, 0xb8, 24, 0); WordSend(27, 0xb8, 36, 0);
WordSend(12, 0xb8, 48, 0); WordSend(13, 0xb8, 0, 1);
WordSend(28, 0xb8, 12, 1); WordSend(29, 0xb8, 24, 1);
WordSend(30, 0xb8, 36, 1);
WordSend(38, 0xba, 48, 0); WordSend(39, 0xba, 0, 1);
WordSend(15, 0xba, 12, 1); WordSend(40, 0xba, 24, 1);
WordSend(41, 0xba, 36, 1); WordSend(42, 0xba, 48, 1);
}
else //温度显示
{
leddis(i);
WordSend(i, 0xb8, 0, 0); WordSend(11, 0xb8, 12, 0);
WordSend(15, 0xb8, 24, 0); WordSend(bw, 0xb8, 36, 0);
WordSend(sw, 0xb8, 48, 0); WordSend(gw, 0xb8, 0, 1);
WordSend(16, 0xb8, 12, 1); WordSend(sf, 0xb8, 18, 1);
WordSend(25, 0xb8, 30, 1); WordSend(25, 0xb8, 42, 1);
WordSend(19, 0xb8, 48, 1);
WordSend(36, 0xba, 0, 0); WordSend(35, 0xba, 12, 0);
WordSend(15, 0xba, 24, 0); WordSend(bw_s, 0xba, 36, 0);
WordSend(sw_s, 0xba, 48, 0);WordSend(gw_s, 0xba, 0, 1);
WordSend(19, 0xba, 12, 1); WordSend(25, 0xba, 24, 1);
WordSend(34, 0xba, 36, 1); WordSend(35, 0xba, 48, 1);
}
}
//主函数
int main(void)
{
MCUInit();
LcdInit();
LcdClear();
sei();
ADC_Init();
INT0_init();
while(1)
{
Key_scan();
if(flag0|flag1)//当有按键按下或AD值更新时才更新显示和输出信号
{
select_ways(a);
BJtoBCD(temp_bj);
ADCtoBCD(ADC_rel);
disp(a);
control_set(w);
//PWM_Init();
if((ADC_rel/10) < temp_h )//控制信号输出
{
/*if(OCR2_NO < 255)
{OCR2_NO++;}*/
sbi(PORTD,PD7);
}
else
{
/*if(OCR2_NO > 0)
{OCR2_NO--;}*/
cbi(PORTD,PD7);
}
flag0 = 0;
flag1 = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -