📄 mainprog.c
字号:
/*
水6月15日 47吨 每吨2.93共137.7元
卫生费24 电共1088,每度0.49元,共1088*0.49=533元。
*/
#include <intrins.h> //含_nop_()函数
#include "SM5964reg.h"
#include "OS_CFG.H"
#include "NewType.h"
#include "SerialNewType.h"
#include "ht1621.h"
//****************************************************************************//
//注意在SerialNewType.h中修改摘机振铃次数(pick_ring_times)供北京铁通使用。 //
//注意如果需要将程序改为拨9次电话不锁机在os_cfg.h中修改CALL9_LOCK_LINE //
//****************************************************************************//
//定义版本号常量
unsigned char code Versoin[]={"070723"};
//中断用全局变量
bit ADC0_open=0; //adc0打开控制
bit ADC1_open=1; //adc1打开控制
bit ADC2_open=0; //adc2打开控制
bit ADC3_open=1; //adc3打开控制
unsigned char timer0_interrupt_counter;
unsigned int ADC_result_intr; //adc结果
unsigned int ADC_result_intr0;
unsigned int ADC_result_intr1;
unsigned int ADC_result_intr2;
unsigned int ADC_result_intr3;
unsigned long ADC1_accumulate_intr; //1通道累加值
unsigned int ADC2_accumulate_intr; //2通道累加值
unsigned int ADC3_accumulate_intr; //3通道累加值
unsigned char ADC2_counter_intr; //adc计数
unsigned char ADC3_counter_intr; //adc计数
//主程序使用变量
unsigned long idata ADC1_accumulate; //1通道累加值
unsigned int ADC_result1,ADC_result2,ADC_result3; //adc结果
float ADC0_coefficient; //adc系数
float ADC1_coefficient; //adc系数
float ADC2_coefficient; //adc系数
float ADC3_coefficient; //adc系数
float idata charge; //累加电荷量
float start_votage; //充电起始电压
float Curent_Votage; //当前电压
float Votage; //电压值
float current; //电流记录
float Capacitance; //电容
float resistance;
unsigned char chip_connect; //芯片是否连接
unsigned char timer0_10ms=0;
unsigned char timer0_0d1s=0;
unsigned char timer0_1s=0;
bit flag_1ms_adc=0;
bit flag_10ms_1=0;
bit flag_0d1s=0;
bit flag_1s_1=0;
unsigned int resistance_measure_1ms=0;
unsigned char data Mesure_state; //侧量状态
unsigned int data Mesure_counter_10ms; //侧量计数
unsigned char data disp_flag; //动态显示电压标志
unsigned char data stop_flag; //停止测试标志
unsigned char data second; //秒
unsigned char data minute; //分钟
unsigned char data hour; //小时
unsigned char Display_state=0;
unsigned char RefreshDisplay_1s=0;
unsigned char MAX_SP=0;
#define timer0_counter_start 65536-(25000/4)*5 +20;
extern bit Ti; //Ti=1,串口准备好,可以发送数据
extern bit SendBufFullFlag; //发送缓冲区满标志
bit RefreshDisplay_0d1s;
void main()
{
//初始化硬件设置。
//WDTC = 0x87; //5964打开看门狗。复位周期限约4秒钟。
WDTC = 0x3f; //stc89le516打开看门狗。复位周期限约4.5秒钟。
//初始化定时器及串口。
IP = 0x02; //T0为高级中断
TMOD = 0x21; //定时器0设为方式1,定时器1设为方式2。
//(方式1:16位计数结构。方式2:8位重置)
//TL0 = 0x00; //普通定时器初值。14745600Hz下,10ms产生一次中断。
//TH0 = 0xd0; //65536-14745600/1200=0xd000
TL0 = 0x00; //12倍速
TH0 = 0xd0; //65536-14745600/1000=0xc666
TL1 = BAUDRATE9600; //定时器一作为波特率发生器。初值
TH1 = BAUDRATE9600; //重装值,BAUDRATE38400作为系统默认值。
PCON = 0x80; //pcon=#80h时,SMOD=1,波特率加倍;
//波特率=(2^SMOD)*(振荡频率/[384(256-TH1)]
SCON = 0x50; //串行口设为方式1,REN=1允许接收。
//定时器1作为波特率发生器,1个起始位,8个数据位,1个停止位。
TCON = 0x50; //启动T0,T1。
P0=0xff;
P0M0=0; //P0为普通I/0
P0M1=0;
P1=0xff;
P1M0=0x0f; //P1.4-01.7推挽输出1,其它为输入
P1M1=0xf0;
P2=0; //各开关均关闭
P3=0xff;
P3M0=0; //P3为普通I/O输入
P3M1=0;
CLK_DIV=0; //时钟分频00=1,01=2,03=4,03=8,04=16,05=32,06=64,07=128
AUXR=0x80; //d7=1,T0为系统时钟,d6=0,T1为系统时钟/12,d5=0,正常串口波特率
//葛同府所写模块初始化函数。
InitialGeTF();
InitialHT1621();
ClearDisplay();
timer0_0d1s=0;
Mesure_state=0;
disp_flag=1; //动态显示电压
ADC_coefficient_measure(); //ADC系数计算
IE = 0x92; //允许T0、串行中断开,开总中断位。
while(1)
{
//清硬件看门狗。
CearHardWatchDog();
Display ();
//葛同府所写任务调用。
TaskGeTF();
//键盘扫描
JP_SM();
//电容测量
Capacitance_Mesure();
}
}
void Timer() interrupt 1
{
//TL0 = 0x1e;
//TH0 = 0xd0; //14745600Hz下,系统时钟/12,10ms产生一次中断计数器初值为0xd000。
TL0 = TL0+0x66;
TH0 = 0xc6; //14745600Hz下,系统时钟/1,1ms产生一次中断计数器初值为0xc666。
if (SP <0x20)
{
// sp_over_flow=1;
if (SP>MAX_SP) MAX_SP=SP; //最大堆栈
}
if (F12_drv==1) F12_drv=0;
else F12_drv=1;
//0通道转换
if (ADC0_open==1){ //adc0打开控制
ADC_CONTR=0xe8+0; //启动AD转换,用最低转换速率
while ((ADC_CONTR & 0x10)==0) {}
ADC_CONTR=0xe0+0; //停止AD转换
ADC_result_intr0 = ADC_HIGH*4;
ADC_result_intr0 +=ADC_LOW & 0x03; //adc结果
}
//1通道转换
if (ADC1_open==1){ //adc1打开控制
ADC_CONTR=0xe8+1; //启动AD转换,用最低转换速率
while ((ADC_CONTR & 0x10)==0) {}
ADC_CONTR=0xe0+1; //停止AD转换
ADC_result_intr1 = ADC_HIGH*4;
ADC_result_intr1 +=ADC_LOW & 0x03; //adc结果
ADC1_accumulate_intr +=ADC_result_intr1; //2通道累加值
}
//2通道转换
if (ADC2_open==1){ //adc2打开控制
ADC_CONTR=0xe8+2; //启动AD转换,用最低转换速率
while ((ADC_CONTR & 0x10)==0) {}
ADC_CONTR=0xe0+2; //停止AD转换
ADC2_accumulate_intr += ADC_HIGH*4;
ADC2_accumulate_intr +=ADC_LOW & 0x03; //adc结果
if (++ADC2_counter_intr>=4) {
ADC2_counter_intr=0;
ADC_result_intr2=ADC2_accumulate_intr/4; //adc计数
ADC2_accumulate_intr=0;
}
}
//3通道转换
if (ADC3_open==1){ //adc3打开控制
ADC_CONTR=0xe8+3; //启动AD转换,用最低转换速率
while ((ADC_CONTR & 0x10)==0) {}
ADC_CONTR=0xe0+3; //停止AD转换
ADC3_accumulate_intr += ADC_HIGH*4;
ADC3_accumulate_intr +=ADC_LOW & 0x03; //adc结果
if (++ADC3_counter_intr>=1) {
ADC3_counter_intr=0;
ADC_result_intr3=ADC3_accumulate_intr/1; //adc计数
ADC3_accumulate_intr=0;
}
}
flag_1ms_adc=1;
resistance_measure_1ms ++;
//timer0中断计数
if (++timer0_interrupt_counter<10) return;
timer0_interrupt_counter=0;
Mesure_counter_10ms++; //侧量计数
flag_10ms_1=1;
if (++timer0_10ms==10) {
timer0_10ms=0;
flag_0d1s=1;
RefreshDisplay_0d1s=1;
if (++ timer0_0d1s==10) {
timer0_0d1s=0;
flag_1s_1=1;
RefreshDisplay_1s++;
if (timer0_1s!=0xff) timer0_1s++;
//disp_char_decimal(second);
if(++second>=60){
second=0;
if(++minute>=60){
minute=0;
if(++hour>=60){
hour=0;
}
}
}
}
}
}
//复位硬件看门狗
void CearHardWatchDog(void)
{
WDTC = 0x3f; //d4:CLR_WDT=1清看门狗,硬件自动清零该位
}
/*
//以十进制方式显示char形数
void disp_char_decimal(unsigned char char_data)
{
unsigned bai,shi,ge;
ge = char_data%10;
char_data = char_data/10;
shi = char_data%10;
bai = char_data/10;
printh(bai + 0x30);
printh(shi + 0x30);
printh(ge + 0x30);
printh(0x20);
}*/
/*
//浮点数打印到串口(最大99999)
void pinint_float_decimal(float float_data)
{
unsigned long long_data;
unsigned char wan,qian,bai,shi,ge;
long_data=(unsigned int)float_data;
ge = long_data%10;
long_data = long_data/10;
shi = long_data%10;
long_data = long_data/10;
bai = long_data%10;
long_data = long_data/10;
qian = long_data%10;
long_data = long_data/10;
wan = long_data%10;
printh(wan + 0x30);
printh(qian + 0x30);
printh(bai + 0x30);
printh(shi + 0x30);
// printh(ge + 0x30);
printh(0x20);
} */
/*
//以十进制方式显示电压,单位V.
void disp_float_votage(float float_data,unsigned char decimal_digits)
{
unsigned long long_data;
unsigned char shiyi,yi,qianwan,baiwan,shiwan,wan,qian,bai,shi,ge;
long_data=(unsigned long)float_data;
ge = long_data%10;
long_data = long_data/10;
shi = long_data%10;
long_data = long_data/10;
bai = long_data%10;
long_data = long_data/10;
qian = long_data%10;
long_data = long_data/10;
wan = long_data%10;
long_data = long_data/10;
shiwan = long_data%10;
long_data = long_data/10;
baiwan = long_data%10;
long_data = long_data/10;
qianwan = long_data%10;
long_data = long_data/10;
yi = long_data%10;
long_data = long_data/10;
shiyi = long_data%10;
if (shiyi!=0) {
printh(shiyi + 0x30);
printh(yi + 0x30);
printh(qianwan + 0x30);
printh(baiwan + 0x30);
printh(shiwan + 0x30);
printh(wan + 0x30);
}
else if (yi!=0) {
printh(yi + 0x30);
printh(qianwan + 0x30);
printh(baiwan + 0x30);
printh(shiwan + 0x30);
printh(wan + 0x30);
}
else if (qianwan!=0) {
printh(qianwan + 0x30);
printh(baiwan + 0x30);
printh(shiwan + 0x30);
printh(wan + 0x30);
}
else if (baiwan!=0) {
printh(baiwan + 0x30);
printh(shiwan + 0x30);
printh(wan + 0x30);
}
else if (shiwan!=0) {
printh(shiwan + 0x30);
printh(wan + 0x30);
}
else if (shiwan!=0) {
printh(shiwan + 0x30);
printh(wan + 0x30);
}
else if (wan!=0) printh(wan + 0x30);
printh(qian + 0x30);
printh('.');
//printh(ge + 0x30);
//显示小数
if(decimal_digits==3){ //3位
printh(bai + 0x30);
printh(shi + 0x30);
printh(ge + 0x30);
}
else if(decimal_digits==1){ //1位
printh(bai + 0x30);
}
else{ //默认2位
printh(bai + 0x30);
printh(shi + 0x30);
//printh(ge + 0x30);
}
printh(0x20);
}
*/
//AD转换
/*
A/D 转换控制寄存器:ADC_CONTR d7 d6 d5 d4 d3 d2 d1 d0
ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0
d2-d0=0通道0,p1.0(12脚)作为ADC0;d2-d0=7通道7,p1.7(19脚)作为ADC7;
SPEED1,SPEED0:模数转换器转换速度控制位
SPEED1/SPEED0为A/D转换所需时间
1 1: 2 1 0 个时钟周期转换一次,CPU工作频率14.7456MHz时,A/D转换速度约70.217KHz,实测约30K
1 0: 4 2 0 个时钟周期转换一次
0 1: 6 3 0 个时钟周期转换一次
0 0: 8 4 0 个时钟周期转换一次
ADC_POWER: ADC 电源控制位。0:关闭ADC 电源;1:打开A/D 转换器电源
ADC_START: 模数转换器(ADC)转换启动控制位,设置为“1”时,开始转换, 转换结束后为0 。
ADC_FLAG: 模数转换器转换结束标志位,当A/D 转换完成后,ADC_FLAG = 1,要由软件清0。
启动AD 转换前一定要确认AD 电源已打开,AD 转换结束后关闭AD 电源可降低功耗,也可不关闭。
初次打开内部A/D 转换模拟电源,需适当延时,等内部模拟电源稳定后,再启动A/D 转换
建议启动A/D 转换后,在A/D 转换结束之前,不改变任何I/O 口的状态,有利于高精度A/D 转换
不管是A/D 转换完成后由该位申请产生中断,还是由软件查询该标志位A/D 转换是否结束,
当A/D 转换完成后,ADC_FLAG = 1,一定要软件清0。
ADC_HIGH / ADC_LOW 特殊功能寄存器: A/D 转换结果特殊功能寄存器
模拟/ 数字转换结果计算公式如下:结果 ( ADC_HIGH[7:0],ADC_LOW[1:0] ) = 1024 x Vin / Vcc
*/
void adc(unsigned char channel)
{
//设置p1口为纯输入状态,用于adc
ADC_CONTR=0xe8+channel; //启动AD转换,用最低转换速率
while ((ADC_CONTR & 0x10)==0) {}
ADC_CONTR=0xe0+channel; //停止AD转换
ADC_result_intr = ADC_HIGH*4;
ADC_result_intr +=ADC_LOW & 0x03; //adc结果
}
//ADC系数计算
//以各通道A/D值乘以系数所得值为毫伏值
void ADC_coefficient_measure(void)
{
unsigned int i;
unsigned long ADC_result_temp;
ADC_result_temp=0;
for (i=0;i<30000;i++){
adc(0); //0通道AD转换1次
ADC_result_temp+=ADC_result_intr;
}
ADC_result_intr=(unsigned int)(ADC_result_temp/i);
ADC_result_intr0=ADC_result_intr;
ADC0_coefficient=(float)2485/ADC_result_intr0; //最大5.3V
//实际51mV,运放输出5.1V,放大倍数为=0.01
//ADC1_coefficient=ADC0_coefficient/100; //实际电阻为100K/1K倍,最大0.053V
ADC1_coefficient=ADC0_coefficient/50; //实际电阻为50K/1K倍,最大0.106V
//实际1.468V,运放输出4.102V,放大倍数为=0.3579
ADC2_coefficient=ADC0_coefficient*3579/10000; //实际电阻为10K/3.3K倍,最大1.9
//实际30.59V,运放输出4.14V,放大倍数为=7.39
ADC3_coefficient=ADC0_coefficient*739/100; //实际电阻为2.6K/20K倍,最大40.77V
}
//带滤波AD转换
//全局变量ADC_result表示滤波后AD值
void ADC_filter(unsigned char channel)
{
adc(channel); //AD转换1次
ADC_result1=ADC_result_intr;
adc(channel); //AD转换1次
ADC_result2=ADC_result_intr;
adc(channel); //AD转换1次
ADC_result3=ADC_result_intr;
if (ADC_result1>=ADC_result2) {
if (ADC_result2>=ADC_result3) ADC_result_intr=ADC_result2; //ADC_result2为中间
else { //ADC_result2最小
if (ADC_result1>ADC_result3) ADC_result_intr=ADC_result3; //ADC_result3为中间
else ADC_result_intr=ADC_result1; //ADC_result1为中间
}
}
else { //ADC_result1<ADC_result2
if (ADC_result2<=ADC_result3) ADC_result_intr=ADC_result2; //ADC_result2为中间
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -