📄 j.c
字号:
/*uchar adr[4]={0x80,0x90,0x88,0x98};//各行显示的起始地址
PB0 DATA
PB1 CLK
PB2 背光
PB3 LED
按钮1 按钮2 按钮3 按钮4
PD7 PD6 PD5 PD4
平时为高,按下时为低
设置/退出 向上/加1 右移/向下 确认/保存
作者:蒋剑东
2005.4.10 于桂林
*/
#include "j.h"
#include <delay.h>
#include <stdio.h>
#include <math.h>
#include "float.h"
#include <io.h>
#include <sleep.h>
#include <Interrupt.h>
#include <sig-avr.h>
#include <inttypes.h>
#include <stdlib.h>
#include <eeprom.h>
#define light_on cbi(PORTB, 2);
#define light_off sbi(PORTB, 2);
#define led_on cbi(PORTB, 3);
#define led_off sbi(PORTB, 3);
void clear_all(void);
unsigned int adc_data;
void adc_init(void);
unsigned int read_adc(unsigned char adc_input);
// 显示用指针变量
char *line1;
char *line2;
char *line3;
char *line4;
EEPROM float ee_tem_cur_jp = +0.00; // 温度电流纠偏
float tem_cur_jp;
EEPROM float ee_chaya_cur_jp = +0.00;// 差压电流纠偏
float chaya_cur_jp;
EEPROM float ee_tem_up = 500.00; // 温度上限
float tem_up;
EEPROM float ee_tem_down = 0.00; // 温度下限
float tem_down;
EEPROM float ee_chaya_up = 7000.00; // 差压上限
float chaya_up;
EEPROM float ee_chaya_down = 0.00; // 差压下限
float chaya_down;
EEPROM float ee_aera = 01.54; // 截面积
float aera;
EEPROM float ee_quanya_up = 10000.00;// 全压上限
float quanya_up;
EEPROM float ee_quanya_down = 0.00; // 全压下限
float quanya_down;
unsigned int x;
uchar change_posion; // 用于存放光标的地址,用于修改数组var_change的值
uchar var_change[10]; // 用于修改参数时暂变量
uchar par_cursor_addres; // 修改参数时,光标的地址,用于显示
uint light_counter=0; // 背光灯计数器
uchar cursor_posion=1;
uint last_ad; // 存放上一次的AD值
uint last_ad_w; // 存放上一次的AD值
uchar var[11]; // 显示变量用的数组
uint timer_counter=0; // 定时器1溢出次数计数器
uchar key_qd=0; // 按键去抖计数器
uchar key_value=0; // 按键值,为0时表示没有按键
uchar screen_status; // 屏幕状态变量
/* 1时为正常模式,显示温度、压力、流量
2时为测试模式,显示温度、压力的AD、电压、电流
3时为主菜单
4时为温度上限
5时为温度下限
6时为差压上限
7时为差压下限
8时为温度电流纠偏
9时为压力电流纠偏
10为截面积输入
11为EEPROM重置
12全压上限
13全压下限
*/
//==========一个十六进制的INT型转换为一个压缩的BCD码INT型=========
unsigned int IntHEXToIntBCD( unsigned int temp )
{
unsigned char a,b;
unsigned int c;
a = temp % 10;
a += ( ( ( temp / 10 ) % 10 ) << 4 );
temp = temp / 100;
b = temp % 10;
b += ( ( ( temp / 10 ) % 10 ) << 4 );
c = b;
c = ( c << 8 );
c += a;
return( c );
}
void cpu_init(void)
{
//----------- IO端口初始化 START -----------------
PORTA = 0x0;
DDRA = 0x0;
PORTB = 0xff;
DDRB = 0xff;
PORTC = 0x0;
DDRC = 0x0;
DDRD = 0x0; // D口配置为输入
PORTD = 0xff; // 使能上拉电阻
//----------- IO端口初始化 END -----------------
//----------- UART端口初始化 START -----------------
UBRRL = 0x33;
UBRRH = 0x00;
UCSRA = 0x00;
UCSRC = 0x86;
UCSRB = 0x18;
//----------- UART端口初始化 END -----------------
//----------- AD端口初始化 START -----------------
SFIOR |= 0x0;
ADMUX = 0x20;
ADCSRA = 0x8e;
//----------- AD端口初始化 END -----------------
//----------- 定时器1初始化 START ----------------- 5MS中断一次
//{{WIZARD_MAP(Timers)
// Timer/Counter0 Clock source: System Clock
// Timer/Counter0 Clock value: Stopped
// Timer/Counter0 Mode: Normal
// Timer/Counter0 Output: Disconnected
OCR0 = 0x00;
TCNT0 = 0x00;
TCCR0 = 0x00;
// Timer/Counter1 Clock source: System Clock
// Timer/Counter1 Clock value: 8000.000kHz
// Timer/Counter1 Mode: Normal
// Timer/Counter1 Output: A: Disconnected, B: Disconnected
OCR1A = 0x9c40;
OCR1B = 0x9c40;
TCNT1 = 0x63c0;
TCCR1A = 0x00;
TCCR1B = 0x01;
// Timer/Counter2 Clock source: System Clock
// Timer/Counter2 Clock value: Stopped
// Timer/Counter2 Mode: Normal
// Timer/Counter2 Output: Disconnected
ASSR = 0x00;
OCR2 = 0x00;
TCNT2 = 0x00;
TCCR2 = 0x00;
TIMSK = 0x04;
//}}WIZARD_MAP(Timers)
//----------- 定时器1初始化 END -----------------
wdt_enable(1); // 看门狗使能 30MS
ACSR = 0x80;
}
//----------- 定时器1中断服务程序 START ----------------- 5MS中断一次
SIGNAL(SIG_OVERFLOW1)
{
// Reinitialize Timer1's value
TCNT1 = 0x63c0;
// TODO: Add your code here
timer_counter++;
light_counter++;
x++;
if( (timer_counter&0x01)==0x00 ) // 10MS检测一次按键
{
if( (PIND&0xff)!=0xff )
{
if ( bit_is_clear(PIND,7) ) // 有按键
{
key_value = 1; // 按键1
}
if ( bit_is_clear(PIND,6) )
{
key_value = 2; // 按键2
}
if ( bit_is_clear(PIND,5) )
{
key_value = 3; // 按键3
}
if ( bit_is_clear(PIND,4) )
{
key_value = 4; // 按键4
}
if ( (PIND&0X60)==0X00 )
{
key_value = 5; // 按键2、3同时按下
}
light_on // 有按键,点亮背光
light_counter = 0;
}
}
if( light_counter>12000 )
{
light_off // 一分钟后熄灭背光,屏幕回到正常状态
//clear_all();
//screen_status = 0x01;
light_counter = 0;
}
if( x>1000 ) x=0; // LED控制
if( x<30 ) led_on // LED控制
else led_off // LED控制
}
//----------- 定时器1中断服务程序 END -----------------
//----------- AD中断服务程序 START -----------------
SIGNAL(SIG_ADC)
{
// Read the ADC conversion result
adc_data = ADCW;
}
//----------- AD中断服务程序 END -----------------
unsigned int read_adc(unsigned char adc_input)
{
// Set ADC input
ADMUX &= 0xE0;
ADMUX |= adc_input;
// MCU sleep
set_sleep_mode(SLEEP_MODE_ADC);
sleep_mode();
return adc_data;
}
/*****************************************
液晶发送子程序(串行)
输入数据:要发送的8位数据
输出:无
作者:
修改时间:2004-08-11
*****************************************/
void lcm_out(char a)
{
char i,d;
for(i=0;i<8;i++)
{
cbi(PORTB,1);
d=a&0x80;
if(d)
sbi(PORTB,0);
else
cbi(PORTB,0);
a<<=1;
sbi(PORTB,1);
}
}
/*****************************************
液晶写控制字程序
输入数据:要写入的8位数据
输出:无
作者:
修改时间:2004-08-11
*****************************************/
void wr_com(uchar a)
{
uchar s,i;
s=a&0xf0;
lcm_out(0xf8);
lcm_out(s);
s=a&0x0f;
s<<=4;
lcm_out(s);
for( i=0;i<254;i++ ) // 延时
{
asm("nop");
}
}
/*****************************************
液晶写数据字程序
输入数据:要写入的8位数据
输出:无
作者:
修改时间:2004-08-11
*****************************************/
void wr_date(uchar a)
{
uchar s,i;
s=a&0xf0;
lcm_out(0xfa);
lcm_out(s);
s=a&0x0f;
s<<=4;
lcm_out(s);
for( i=0;i<254;i++ ) // 延时
{
asm("nop");
}
}
/*****************************************
液晶初始化程序
输入数据:无
输出:无
作者:
修改时间:2004-08-11
*****************************************/
void lcm_init(void)
{
wr_com(0x30);
delay(1,8000);
wr_com(0x30);
delay(1,8000);
wr_com(0x0c);
delay(1,8000);
wr_com(0x01); // 清屏
delay(10,8000); // 清屏
wr_com(0x60);
delay(1,8000);
}
void clear_all(void)
{
wr_com(0x01); // 清屏
delay(1,8000); // 清屏
}
//----------- 整行显示函数 START -----------------
void display(void)
{
wr_com(0x80);
while( *line1!=0x00 )
{
wr_date(*line1);
line1++;
}
wr_com(0x90);
while( *line2!=0x00 )
{
wr_date(*line2);
line2++;
}
wr_com(0x88);
while( *line3!=0x00 )
{
wr_date(*line3);
line3++;
}
wr_com(0x98);
while( *line4!=0x00 )
{
wr_date(*line4);
line4++;
}
line1 = "";
line2 = "";
line3 = "";
line4 = "";
}
//----------- 整行显示函数 END -----------------
//----------- 系统初始化函数 START -----------------
void system_init(void)
{
line1 = "";
line2 = "";
line3 = "";
line4 = "";
light_on
led_on
lcm_init();
sei(); // 开放全局中断
screen_status = 1; // 主菜单状态为显示温度、压力、流量(正常模式)
UDR='R'; // 用于复位指示
while(!(UCSRA&0X40));
UCSRA|=0x40;
clear_all();
line1 = "";
line2 = " 驻室式 ";
line3 = "气体流量测量仪";
line4 = "";
display();
delay(1000,8000);
clear_all();
eeprom_read_block(&tem_cur_jp, &ee_tem_cur_jp, sizeof(float));
eeprom_read_block(&chaya_cur_jp,&ee_chaya_cur_jp, sizeof(float));
eeprom_read_block(&tem_up, &ee_tem_up, sizeof(float));
eeprom_read_block(&tem_down, &ee_tem_down, sizeof(float));
eeprom_read_block(&chaya_up, &ee_chaya_up, sizeof(float));
eeprom_read_block(&chaya_down, &ee_chaya_down, sizeof(float));
eeprom_read_block(&aera, &ee_aera, sizeof(float));
eeprom_read_block(&quanya_up, &ee_quanya_up, sizeof(float));
eeprom_read_block(&quanya_down, &ee_quanya_down, sizeof(float));
}
//----------- 系统初始化函数 END -----------------
uint read_ad( uchar channel )
{
uint ad;
uint sum_ad = 0; // AD值求和
uchar i = 0; // 取平均值次数
for( i=0;i<50;i++ )
{
ad = ( read_adc(channel)>>6 );
sum_ad += ad;
asm("wdr");
}
ad = sum_ad/50;
if( (ad>3) & (ad<1020) )
{
if( ad>last_ad )
{
if ( ad-last_ad==1 ) ad--;
else if ( ad-last_ad==2 ) ad-=2;
else if ( ad-last_ad==3 ) ad-=3;
}
else if( ad<last_ad )
{
if ( last_ad-ad==1 ) ad++;
else if ( last_ad-ad==2 ) ad+=2;
else if ( last_ad-ad==3 ) ad+=3;
}
last_ad = ad;
}
return(ad);
}
uint lb( uint x )
{
if( (x>3) & (x<1020) )
{
if( x>last_ad_w )
{
if ( x-last_ad_w==1 ) x--;
else if ( x-last_ad_w==2 ) x-=2;
else if ( x-last_ad_w==3 ) x-=3;
}
else if( x<last_ad )
{
if ( last_ad_w-x==1 ) x++;
else if ( last_ad_w-x==2 ) x+=2;
else if ( last_ad_w-x==3 ) x+=3;
}
last_ad_w = x;
}
return(x);
}
//----------- 变量显示函数 START -----------------
void display_variable( uchar addres,uchar counter ) // addres--地址 counter---要显示的位数(包括小数点)
{
uchar i;
wr_com(addres);
for( i=0;i<counter;i++ )
{
wr_date(var[i]);
}
}
//----------- 变量显示函数 END -----------------
//----------- 变量显示函数 START -----------------
void display_variable1( uchar addres,uchar counter ) // addres--地址 counter---要显示的位数(包括小数点)
{
uchar i;
for( i=0;i<counter;i++ )
{
wr_com(addres);
wr_date(var_change[i]);
addres++;
}
}
//----------- 变量显示函数 END -----------------
void display_main_menu1(void)
{
line1 = "1.温度上限";
line2 = "2.温度下限";
line3 = "3.差压上限";
line4 = "4.差压下限";
wr_com(0x81);
while( *line1!=0x00 )
{
wr_date(*line1);
line1++;
}
wr_com(0x91);
while( *line2!=0x00 )
{
wr_date(*line2);
line2++;
}
wr_com(0x89);
while( *line3!=0x00 )
{
wr_date(*line3);
line3++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -