不断更新
锁存器、晶体管显示驱动代码、延时函数
void Delay(unsigned int xms) //@12.000MHz
{
while(xms--){
unsigned char data i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
#include <STC15F2K60S2.H>
#include "Delay.h"
void InitHC138(unsigned char channel){
switch(channel){
case 0:P2 = (P2 & 0x1f) | 0x00;break;
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
}
}
void OutPutP0(unsigned char channel,unsigned char dat){
InitHC138(0);
P0 = dat;
InitHC138(channel);
InitHC138(0);
}
void ShowSMG(unsigned char pos,unsigned char dat){
OutPutP0(6,(0x01 << (pos - 1)));
OutPutP0(7,dat);
Delay(1);
}
void Initsys(){
OutPutP0(4,0xff);
OutPutP0(5,0x00);
OutPutP0(6,0xff);
OutPutP0(7,0xff);
}
目录
第8届
底层驱动代码的改动
I2C通讯
开头加上
#include <STC15F2K60S2.H>
#include "intrins.h"
sbit sda = P2^1;
sbit scl = P2^0;
EEPROM存储读取驱动
void I2CWriteByte(unsigned char addr,unsigned char dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned char I2CReadByte(unsigned char addr){
unsigned char dat;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
dat = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return dat;
}
DAC转换驱动
void I2CDACWriteByte(unsigned char dat){
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
核心代码
12μs延时函数:
#include "intrins.h"
void Delay12us(void) //@12.000MHz
{
unsigned char data i;
_nop_();
_nop_();
i = 33;
while (--i);
}
#include <STC15F2K60S2.H>
#include "Delay.h"
#include "InitHC138.h"
#include "iic.h"
sbit TX = P1^0;
sbit RX = P1^1;
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf //-
};
unsigned int time = 0;
unsigned int distance = 0;//当前测量的距离
unsigned int distance_view = 0;//想要查看的距离
unsigned char cishu;//测量次数
unsigned int dislast = 0;//上次测量的距离
unsigned int dissum = 0;//本次与上次的测量的和
bit caozuo = 0;//操作
bit suc = 0;//测量成功标志位
unsigned char datnum = 0;//数据编号
unsigned char mangquset = 0;//盲区参数
unsigned char mangqu = 0;
unsigned char cishu;//测量次数
unsigned char led_stat = 0xff;
unsigned int count = 0;//数秒数
unsigned char showmode = 0;//显示选择代号
unsigned char shuchu = 0;
//*********************************超声波测量
void fangbo(){//产生方波
unsigned char i;
for(i = 0;i < 8;i++){
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void ceju(){//测距
TMOD &= 0x0f; //设置定时器模式
TL1 = 0x00; //设置定时初始值
TH1 = 0x00;
fangbo();
TR1 = 1;
while((TF1 == 0) && (RX == 1));
TR1 = 0;
if(TF1 == 0){
suc = 1;//测量成功
TR0 = 1; //定时器0开始计时
time = (TH1 << 8) | TL1;
distance = time * 0.017;
I2CWriteByte(cishu,distance);
cishu++;
cishu %= 10;
Delay(10);
TL1 = 0x00; TH1 = 0x00;
}else{
TF1 = 0;
}
}
//*********************************测量成功后闪灯
void Timer0_Isr(void) interrupt 1
{
count++;
if(suc){
if(((count % 20) == 0) && ((count % 40) != 0)){
led_stat = led_stat & 0xfe;OutPutP0(4,led_stat);
}else if((count % 40) == 0){
led_stat = led_stat | 0x01;OutPutP0(4,led_stat);
}
if(count == 400){
led_stat = led_stat | 0x01;OutPutP0(4,led_stat);
count = 0;
suc = 0;//退出闪灯
TR0 = 0;
}
}
}
void Timer0_Init(void) //10毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xF0; //设置定时初始值
TH0 = 0xD8; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1; //使能定时器0中断
EA = 1;
}
//*********************************
//*********************************测距显示界面
void xianshi(){
led_stat = (led_stat & 0x3f) | 0xc0;OutPutP0(4,led_stat);
if(cishu > 1){
dislast = I2CReadByte((cishu-2));
Delay(5);
}
ShowSMG(1,Seg_Table[caozuo]);
ShowSMG(6,Seg_Table[distance / 100]);
ShowSMG(7,Seg_Table[distance / 10 % 10]);
ShowSMG(8,Seg_Table[distance % 10]);
if(caozuo == 0){
ShowSMG(5,Seg_Table[dislast % 10]);
if(dislast > 9){
ShowSMG(4,Seg_Table[dislast / 10 % 10]);
}
if(dislast > 99){
ShowSMG(3,Seg_Table[dislast / 100]);
}
}
if(caozuo == 1){
dissum = I2CReadByte((cishu-2)) + I2CReadByte((cishu-1));
ShowSMG(5,Seg_Table[dissum % 10]);
if(dissum > 9){
ShowSMG(4,Seg_Table[dissum / 10 % 10]);
}
if(dissum > 99){
ShowSMG(3,Seg_Table[dissum / 100]);
}
}
}
//*********************************
//*********************************数据回显界面
void showecho(){
led_stat = (led_stat & 0x3f) | 0x40;OutPutP0(4,led_stat);
distance_view = I2CReadByte(datnum);
ShowSMG(1,Seg_Table[datnum / 10]);
ShowSMG(2,Seg_Table[datnum % 10]);
ShowSMG(6,Seg_Table[distance_view / 100]);
ShowSMG(7,Seg_Table[distance_view / 10 % 10]);
ShowSMG(8,Seg_Table[distance_view % 10]);
}
//*********************************
//*********************************参数设置界面
void canshu(){
led_stat = (led_stat & 0x3f) | 0x80;OutPutP0(4,led_stat);
ShowSMG(1,Seg_Table[15]);
ShowSMG(7,Seg_Table[mangquset / 10]);
ShowSMG(8,Seg_Table[mangquset % 10]);
}
//*********************************选择显示
void showselect(){
switch(showmode){
case 0:xianshi();break;
case 1:showecho();break;
case 2:canshu();break;
}
}
//*********************************
//*********************************模拟信号输出
void DACshuchu(){
if(distance <= mangqu){
I2CDACWriteByte(0);
}else{
shuchu = (distance - mangqu) * 51 / 100;
if(shuchu > 255){
I2CDACWriteByte(255);
}else{
I2CDACWriteByte(shuchu);
}
}
}
//*********************************
//*********************************按键扫描
void scankey(){
if(showmode == 0){
if(P33 == 0){//S4
Delay(5);
ceju();
Delay(5);
while(P33 == 0){
showselect();
}
}
if(P30 == 0){//S7
Delay(5);
if(caozuo){
caozuo = 0;
}else{
caozuo = 1;
}
while(P30 == 0){
showselect();
}
}
if(P32 == 0){//S5
Delay(5);
showmode = 1;
while(P32 == 0){
showselect();
}
}
if(P31 == 0){//S6
Delay(5);
showmode = 2;
while(P31 == 0){
showselect();
}
}
}
if(showmode == 1){//S5
if(P32 == 0){
Delay(5);
showmode = 0;
while(P32 == 0){
showselect();
}
}
if(P31 == 0){//S6
Delay(5);
showmode = 2;
while(P31 == 0){
mangqu = mangquset;
showselect();
}
}
if(P30 == 0){//S7
Delay(5);
datnum++;
datnum %= 10;
while(P30 == 0){
showselect();
}
}
}
if(showmode == 2){
if(P32 == 0){//S5
Delay(5);
showmode = 1;
while(P32 == 0){
showselect();
}
}
if(P31 == 0){//S6
Delay(5);
showmode = 0;
while(P31 == 0){
mangqu = mangquset;
showselect();
}
}
if(P30 == 0){//S7
Delay(5);
mangquset += 10;
mangquset %= 100;
while(P30 == 0){
showselect();
}
}
}
}
//*********************************
void main(){
Timer0_Init();
Initsys();
while(1){
scankey();
showselect();
DACshuchu();
}
}
g0801
第9届
底层驱动代码的改动
I2C通讯
开头加上:
#include <STC15F2K60S2.H>
#include "intrins.h"
sbit sda = P2^1;
sbit scl = P2^0;
RB2读取
unsigned char dianyaRead(){
unsigned char dianya;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
dianya = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return dianya;
}
EEPROM读取与写入
void eepromWrite(unsigned char addr,unsigned char dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned char eepromRead(unsigned char addr){
unsigned char dat;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
dat = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return dat;
}
DS18B20
开头加上:
#include <STC15F2K60S2.H>
sbit DQ = P1^4;
结尾延时数据全部乘以12
核心代码
#include <STC15F2K60S2.H>
#include "Delay.h"
#include "InitHC138.h"
#include "iic.h"
#include "onewire.h"
void wendu();
void showselect();
void scankey();
void showselectonly();
code unsigned char Seg_Table[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf //-
};
unsigned int dianya = 0;//读取RB2的电压值
unsigned int count_hz = 0;//数频率
unsigned int tmp = 0;//读取频率
unsigned char count = 0;//计时秒数
unsigned int temp = 0;//温度
unsigned char celiangmode = 0;//测量模式代号
unsigned char huixianmode = 0;//回显模式代号
unsigned char mode = 0;//测量、回显、参数代号
unsigned int tempecho = 0;//回显温度
unsigned int hzecho = 0;//回显频率
unsigned int hzo = 0;//还原后的频率
unsigned int dianyaecho = 0;//回显电压数字
unsigned char yuzhi = 1;//电压阈值
bit freeze = 0;//按下按键禁止读取温度
bit key_stat = 0;//按键状态
unsigned int count_key = 0;//计算按键按下的时间长度
unsigned char led_set = 0xfe;
unsigned char count_s;
//************************************定时器测量频率
void Timer0_Isr(void) interrupt 1
{
count_hz++;
}
void Timer1_Isr(void) interrupt 3
{
count++;
count_s++;
if(key_stat){
count_key++;
}
if(dianya > yuzhi){
if(((count_s % 20) == 0) && ((count_s % 40) != 0)){
led_set = led_set & 0x7f;OutPutP0(4,led_set);
}else if((count_s % 40) == 0){
led_set = led_set | 0x80;OutPutP0(4,led_set);
}
if(count_s == 255){
count_s = 0;
}
}else{
led_set = led_set | 0x80;OutPutP0(4,led_set);
}
if(count == 100){
tmp = count_hz;
count_hz = 0;
count = 0;
}
}
void Timer_Init(void) //10毫秒@12.000MHz
{
TMOD = 0x07; //设置定时器模式
TL0 = 0xff;
TH0 = 0xff;
TL1 = 0xF0; //设置定时初始值
TH1 = 0xD8; //设置定时初始值
TF1 = 0; //清除TF1标志
TF0 = 0;
TR1 = 1; //定时器1开始计时
TR0 = 1;
ET1 = 1; //使能定时器1中断
ET0 = 1;
EA = 1;
}
//************************************
//************************************温度测量
void DelaySMG(unsigned char xms){
while(xms--){
showselectonly();
Delay(1);
}
}
void wenduceliang(){
unsigned char LSB,MSB;
unsigned char i;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
for(i = 0;i < 10;i++){
switch(celiangmode){
case 0:led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
case 1:led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
case 2:led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
}
scankey();DelaySMG(15);
}
switch(celiangmode){
case 0:led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
case 1:led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
case 2:led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
}
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = (MSB << 8) | LSB;
temp = temp * 6.25;
}
//************************************
//************************************数据显示界面
void showdat(){
dianya = dianyaRead();
dianya = (dianya *10) / 51;
ShowSMG(1,0xc1);
ShowSMG(7,Seg_Table[dianya / 10 % 10] & 0x7f);
ShowSMG(8,Seg_Table[dianya % 10]);
}
//************************************
//************************************频率测量显示
void showhz(){
ShowSMG(1,Seg_Table[15]);
ShowSMG(8,Seg_Table[tmp % 10]);
if(tmp > 9){
ShowSMG(7,Seg_Table[tmp / 10 % 10]);
}
if(tmp > 99){
ShowSMG(6,Seg_Table[tmp / 100 % 10]);
}
if(tmp > 999){
ShowSMG(5,Seg_Table[tmp / 1000 % 10]);
}
if(tmp > 9999){
ShowSMG(4,Seg_Table[tmp / 10000 % 10]);
}
}
//************************************
//************************************温度显示界面
void wendu(){
ShowSMG(1,Seg_Table[12]);
ShowSMG(5,Seg_Table[temp / 1000]);
ShowSMG(6,Seg_Table[temp / 100 % 10] & 0x7f);
ShowSMG(7,Seg_Table[temp / 10 % 10]);
ShowSMG(8,Seg_Table[temp % 10]);
}
//************************************
//************************************数据回显界面
void showecho(){
ShowSMG(1,0x89);
if(huixianmode == 0){
tempecho = (eepromRead(0x00) * 100);
Delay(1);
tempecho = tempecho + (eepromRead(0x01));
Delay(1);
ShowSMG(2,Seg_Table[12]);
ShowSMG(5,Seg_Table[tempecho / 1000]);
ShowSMG(6,Seg_Table[tempecho / 100 % 10] & 0x7f);
ShowSMG(7,Seg_Table[tempecho / 10 % 10]);
ShowSMG(8,Seg_Table[tempecho % 10]);
}
if(huixianmode == 1){
OutPutP0(4,0xff);
hzecho = (eepromRead(0x02) * 10000);
Delay(1);
hzecho = hzecho + (eepromRead(0x03) * 100);
Delay(1);
hzecho = hzecho + eepromRead(0x04);
Delay(1);
ShowSMG(2,Seg_Table[15]);
ShowSMG(8,Seg_Table[hzo % 10]);
if(hzecho > 9){
ShowSMG(7,Seg_Table[hzecho / 10 % 10]);
}
if(hzecho > 99){
ShowSMG(6,Seg_Table[hzecho / 100 % 10]);
}
if(hzecho > 999){
ShowSMG(5,Seg_Table[hzecho / 1000 % 10]);
}
if(hzecho > 9999){
ShowSMG(4,Seg_Table[hzecho / 10000 % 10]);
}
}
if(huixianmode == 2){
OutPutP0(4,0xff);
dianyaecho = eepromRead(0x05);
Delay(2);
ShowSMG(2,0xc1);
ShowSMG(7,Seg_Table[dianyaecho / 10] & 0x7f);
ShowSMG(8,Seg_Table[dianyaecho % 10]);
}
}
//************************************
//************************************电压阈值设置界面
void dianyayuzhi(){
ShowSMG(1,0x8c);
ShowSMG(7,Seg_Table[yuzhi / 10] & 0x7f);
ShowSMG(8,Seg_Table[yuzhi % 10]);
}
//************************************
//************************************按键扫描
void scankey(){
unsigned char tmp1 = 0;
if(mode == 0){//在数据显示界面
if(P33 == 0){//S4
Delay(5);
freeze = 1;
celiangmode++;
celiangmode %= 3;
switch(celiangmode){
case 0:led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
case 1:led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
case 2:led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
}
while(P33 == 0){
showselectonly();
}
freeze = 0;
}
if(P32 == 0){//S5
tmp1 = temp / 100;
eepromWrite(0x00,tmp1);Delay(2);
tmp1 = temp % 100;
eepromWrite(0x01,tmp1);Delay(2);
tmp1 = tmp / 10000;
eepromWrite(0x02,tmp1);Delay(2);
tmp1 = tmp / 100 % 100;
eepromWrite(0x03,tmp1);Delay(2);
tmp1 = tmp % 100;
eepromWrite(0x04,tmp1);Delay(2);
tmp1 = dianya;
eepromWrite(0x05,tmp1);Delay(2);
}
if(P31 == 0){//S6
Delay(5);
freeze = 1;
mode = 1;
while(P31 == 0){
showselectonly();
}
freeze = 0;
}
if(P30 == 0){//S7
Delay(5);
freeze = 1;
mode = 2;
while(P30 == 0){
showselectonly();
}
freeze = 0;
}
}
if(mode == 1){//回显模式下
if(P31 == 0){//S6
Delay(5);
freeze = 1;
mode = 0;
while(P31 == 0){
showselectonly();
}
freeze = 0;
}
if(P33 == 0){//S4
Delay(5);
freeze = 1;
huixianmode++;
huixianmode %= 3;
while(P33 == 0){
showselectonly();
}
freeze = 0;
}
if(P30 == 0){//S7
Delay(5);
freeze = 1;
huixianmode++;
huixianmode %= 3;
while(P30 == 0){
showselectonly();
}
freeze = 0;
}
}
if(mode == 2){//电压阈值设置模式下
if(P31 == 0){//S6
Delay(5);
key_stat = 1;
yuzhi++;
yuzhi %= 51;
while(P31 == 0){
showselectonly();
if(count_key >= 80){
yuzhi++;
yuzhi %= 51;
DelaySMG(20);
}
}
key_stat = 0;
count_key = 0;
}
if(P30 == 0){//S7
Delay(5);
freeze = 1;
mode = 0;
while(P30 == 0){
showselectonly();
}
freeze = 0;
}
}
}
//************************************
//************************************选择显示
void showselect(){
if(mode == 0){
switch(celiangmode){
case 0:wenduceliang();wendu();led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
case 1:showhz();led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
case 2:showdat();led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
}
}
if(mode == 1){
OutPutP0(4,0xff);
showecho();
}
if(mode == 2){
OutPutP0(4,0xff);
dianyayuzhi();
}
}
void showselectonly(){
if(mode == 0){
switch(celiangmode){
case 0:wendu();break;
case 1:showhz();break;
case 2:showdat();break;
}
}
if(mode == 1){
OutPutP0(4,0xff);
showecho();
}
if(mode == 2){
OutPutP0(4,0xff);
dianyayuzhi();
}
}
//************************************
void main(){
Initsys();
Timer_Init();
while(1){
showselect();
scankey();
}
}
g0901
第十届
底层驱动代码的改动
I2C通讯
开头略
void eepromwrite(unsigned char addr,unsigned char dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned char eepromread(unsigned char addr){
unsigned char tmp;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
tmp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return tmp;
}
void DAC(unsigned char dat){
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
DS18B20
略
核心代码
#include <STC15F2K60S2.H>
#include "Delay.h"
#include "InitHC138.h"
#include "onewire.h"
#include "iic.h"
#include "stdio.h"
void showselect();
void scankey();
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf
};
unsigned mode = 0;//模式代号
unsigned char shuju = 0;//数据界面代号
unsigned char canshu = 0;//参数界面代号
bit wendu = 0;//是否进行测量
unsigned int time = 0;//超声波时间
unsigned int distance = 0;//测距距离
unsigned int temp = 0;//温度
unsigned int biangeng = 0;//参数变化情况
unsigned char tempcert = 30;//温度参数确定
unsigned char distancecert = 35;//距离参数确定
char tempset = 30;//温度参数设定
char distanceset = 35;//距离参数设定
bit keystat = 0;//按键状态
bit DACstat = 0;//DAC启用状态
unsigned char count = 0;//计时器
unsigned char ledstat = 0xff;//按键状态
unsigned char command[10] = {0};//命令字符存储
unsigned char num = 0;//命令字符数组下标
//**********************************串口
void Uart1_Isr(void) interrupt 4
{
if (RI) //检测串口1接收中断
{
command[num] = SBUF;
RI = 0; //清除串口1接收中断请求位
num++;
}
}
void Uart1_Init(void) //4800bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0xCC; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
}
void sendbtye(unsigned char dat){
SBUF = dat;
while(TI == 0);
TI = 0;
}
void sendstring(unsigned char *str){
while(*str != '\0'){
sendbtye(*str++);
}
}
//**********************************
//**********************************定时器
void Timer0_Isr(void) interrupt 1
{
if(keystat){
count++;
}
}
void Timer0_Init(void) //50毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xB0; //设置定时初始值
TH0 = 0x3C; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
//**********************************
//**********************************超声波与显示
sbit TX = P1^0;
sbit RX = P1^1;
void fangbo(){
unsigned char i = 0;
for(i = 0;i < 8;i++){
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void ceju(){
TMOD &= 0x0F;
TL1 = 0x00; //设置定时初始值
TH1 = 0x00;
fangbo();
TR1 = 1;
while((RX == 1) && (TF1 == 0));
TR1 = 0;
if(TF1 == 0){
time = (TH1 << 8) | TL1;
distance = time * 0.017;
}else{
TF1 = 0;
distance = 99;
}
}
void showdistance(){
ceju();
ShowSMG(1,0xc7);
ShowSMG(7,Seg_Table[distance / 10]);
ShowSMG(8,Seg_Table[distance % 10]);
}
//**********************************
//**********************************温度与温度显示
void delaysmg(unsigned char xms){
while(xms--){
showselect();
Delay(1);
}
}
void DS18B20read(){
unsigned char LSB,MSB;
unsigned char i;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
wendu = 1;
for(i = 0;i<20;i++){
delaysmg(10);scankey();
}
wendu = 0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = (MSB << 8) | LSB;
temp = temp * 6.25;
}
void cewen(){
ShowSMG(1,Seg_Table[15]);
ShowSMG(5,Seg_Table[temp / 1000]);
ShowSMG(6,Seg_Table[temp / 100 % 10] & 0x7f);
ShowSMG(7,Seg_Table[temp / 10 % 10]);
ShowSMG(8,Seg_Table[temp % 10]);
}
//**********************************
//**********************************变更次数显示
void biangengcishu(){
ShowSMG(1,0xc8);
ShowSMG(8,Seg_Table[biangeng % 10]);
if(biangeng > 9){
ShowSMG(7,Seg_Table[biangeng / 10 % 10]);
}
if(biangeng > 99){
ShowSMG(6,Seg_Table[biangeng / 100 % 10]);
}
if(biangeng > 999){
ShowSMG(5,Seg_Table[biangeng / 1000 % 10]);
}
if(biangeng > 9999){
ShowSMG(4,Seg_Table[biangeng / 10000 % 10]);
}
}
//**********************************
//**********************************//参数界面
void wenduset(){//温度参数
ShowSMG(1,0x8C);
ShowSMG(4,Seg_Table[1]);
ShowSMG(7,Seg_Table[tempset / 10]);
ShowSMG(8,Seg_Table[tempset % 10]);
}
void disset(){//距离参数
ShowSMG(1,0x8C);
ShowSMG(4,Seg_Table[2]);
ShowSMG(7,Seg_Table[distanceset / 10]);
ShowSMG(8,Seg_Table[distanceset % 10]);
}
//**********************************
//**********************************DAC
void DACshow(){
if(DACstat == 0){
DAC(22);
}else{
if(distance <= distancecert){
DAC(102);
}else{
DAC(204);
}
}
}
//**********************************
//**********************************显示选择
void showshuju(){
switch(shuju){
case 0:if(wendu == 0){DS18B20read();}cewen();break;
case 1:showdistance();break;
case 2:biangengcishu();break;
}
}
void showcanshu(){
switch(canshu){
case 0:wenduset();break;
case 1:disset();break;
}
}
void showselect(){
switch(mode){
case 0:showshuju();break;
case 1:showcanshu();break;
}
}
//**********************************
//**********************************按键扫描
void scankey(){
P32 = 0;P33 = 1;
P35 = 1;P34 = 1;
if(P35 == 0){//S13
Delay(5);
keystat = 1;
while(P35 == 0){
showselect();
}
keystat = 0;
if(mode == 1){
if((tempcert != tempset) || (distancecert != distanceset)){
tempcert = tempset;
distancecert = distanceset;
biangeng++;
eepromwrite(0x00,(biangeng));
Delay(2);
eepromwrite(0x01,(biangeng >> 8));
Delay(2);
}
}
if(count <= 20){
mode++;
mode %= 2;
count = 0;
}
if(count > 20){
DACstat = ~DACstat;
count = 0;
}
}
if(P34 == 0){//S17
Delay(5);
if(mode == 1){
if(canshu == 0){
tempset = tempset + 2;
if(tempset > 99){
tempset = 0;
}
}
if(canshu == 1){
distanceset = distanceset + 5;
if(distanceset > 99){
distanceset = 0;
}
}
}
while(P34 == 0){
showselect();
}
}
P32 = 1;P33 = 0;
P35 = 1;P34 = 1;
if(P35 == 0){//S12
Delay(5);
keystat = 1;
while(P35 == 0){
showselect();
}
keystat = 0;
if(count <= 20){
if(mode == 0){
shuju++;
shuju %= 3;
}
if(mode == 1){
canshu++;
canshu %= 2;
}
count = 0;
}
if(count > 20){
biangeng = 0;
count = 0;
eepromwrite(0x00,(biangeng));Delay(2);
eepromwrite(0x01,(biangeng >> 8));Delay(2);
}
}
if(P34 == 0){//S16
Delay(5);
if(mode == 1){
if(canshu == 0){
tempset = tempset - 2;
if(tempset < 0){
tempset = 99;
}
}
if(canshu == 1){
distanceset = distanceset - 5;
if(distanceset < 0){
distanceset = 99;
}
}
}
while(P34 == 0){
showselect();
}
}
}
//**********************************
//**********************************LED
void led(){
if(temp > tempcert * 100){
ledstat = ledstat & 0xfe;OutPutP0(4,ledstat);
}else{
ledstat = ledstat | 0x01;OutPutP0(4,ledstat);
}
if(distance > distancecert){
ledstat = ledstat & 0xfd;OutPutP0(4,ledstat);
}else{
ledstat = ledstat | 0x02;OutPutP0(4,ledstat);
}
if(DACstat){
ledstat = ledstat & 0xfb;OutPutP0(4,ledstat);
}else{
ledstat = ledstat | 0x04;OutPutP0(4,ledstat);
}
}
//**********************************
//**********************************串口收发数据
void working(){
unsigned char tmp = 0;
if((command[0] == 'S') && (command[1] == 'T')){
printf("$%d,%d.%d\r\n",(int)distance,(temp / 100),(temp % 100));
num = 0;
for(tmp = 0;tmp < 10;tmp++){
command[tmp] = 0;
}
}
if((command[0] == 'P') && (command[1] == 'A')){
printf("$%d,%d\r\n",(int)tempcert,(int)distancecert);
num = 0;
for(tmp = 0;tmp < 10;tmp++){
command[tmp] = 0;
}
}else if(command[0] != 0){
printf("ERROR\r\n");
num = 0;
for(tmp = 0;tmp < 10;tmp++){
command[tmp] = 0;
}
}
}
//**********************************
void main(){
Initsys();
Timer0_Init();
//eepromwrite(0x00,0);Delay(2);
//eepromwrite(0x01,0);Delay(2);
Uart1_Init();
biangeng = (eepromread(0x00) | (eepromread(0x01) << 8));
while(1){
scankey();
showselect();
DACshow();
led();
working();
}
}
char putchar(char ch)//重定向printf
{
sendbtye(ch);
return ch;
}
G1002按键操作部分
g1003DAC部分
G1001串口通讯部分
第十四届
底层驱动代码的改动
略
核心代码
#include <STC15F2K60S2.H>
#include "delay.h"
#include "inithc138.h"
#include "onwire.h"
#include "iic.h"
#define dt 10
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf
};
unsigned char mode = 0;//模式代号
bit unit = 0;//单位选择
bit canshu = 0;//参数选择
bit ce = 0;
unsigned char set = 0;//设置选择
unsigned int distance = 0;//距离
unsigned int time = 0;//超神波时间
unsigned int v = 340;//介质声速
unsigned int temp = 0;//温度
unsigned char n = 0;
unsigned int temprec[10] = {0};
unsigned int disrec[10] = {0};
unsigned char disset = 40;//距离参数
char tempset = 30;//温度参数
bit shuangan = 0;//按键是否都按下
unsigned int count = 0;//计时
bit shuchu = 0;
bit jilu = 0;
unsigned int count2 = 0;
unsigned char factory = 0;
char disjiao = 0;//距离校准值
unsigned char dac = 10;
unsigned char ledstat = 0xff;
unsigned char count_s = 0;
bit flag = 0;
//***********************************超声波测距和测温
void showselect();
void scankey();
sbit TX = P1^0;
sbit RX = P1^1;
void fangbo(){
unsigned char i;
for(i = 0;i < 8;i++){
TX = 1;
Delay13us();
TX = 0;
Delay13us();
}
}
void ceju(){
CMOD = 0x00; //设置定时器模式
CL = 0x00; //设置定时初始值
CH = 0x00; //设置定时初始值
CF = 0;
CR = 0;
fangbo();
CR = 1;
while((RX == 1) && (CH < 0x17));
CR = 0;
if(RX == 0){
RX = 1;
time = (CH << 8) | CL;
distance = ((time * 0.017) * v / 340) + disjiao;
if(jilu == 1)disrec[n] = distance;
}else{
CF = 0;
distance = 9999;
}
}
void Delaysmg(unsigned char xms){
while(xms--){
showselect();
Delay(1);
}
}
void cewen(){
unsigned char LSB,MSB;
unsigned char i;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
ce = 1;
for(i = 0;i < 40;i++){
Delaysmg(2);scankey();ceju();
}
ce = 0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = (MSB << 8) | LSB;
temp = temp * 0.625;
if(jilu == 1){temprec[n] = temp;n++;}
}
void showdistemp(){
showsmg(1,Seg_Table[temp / 100]);
showsmg(2,Seg_Table[temp / 10 % 10] & 0x7f);
showsmg(3,Seg_Table[temp % 10]);
showsmg(4,Seg_Table[16]);
showsmg(8,Seg_Table[distance % 10]);
if(unit == 0){
if(distance > 9){
showsmg(7,Seg_Table[distance / 10 % 10]);
}
if(distance > 99){
showsmg(6,Seg_Table[distance / 100 % 10]);
}
if(distance > 999){
showsmg(5,Seg_Table[distance / 1000 % 10]);
}
}else if(unit == 1){
showsmg(7,Seg_Table[distance / 10 % 10]);
showsmg(6,Seg_Table[distance / 100 % 10] & 0x7f);
if(distance > 999){
showsmg(5,Seg_Table[distance / 1000 % 10]);
}
if(distance > 9999){
showsmg(5,Seg_Table[distance / 10000 % 10]);
}
}
}
//***********************************参数界面
void showset(){
showsmg(1,0x8c);
if(canshu == 0){
showsmg(2,Seg_Table[1]);
showsmg(7,Seg_Table[disset / 10]);
showsmg(8,Seg_Table[disset % 10]);
}else if(canshu == 1){
showsmg(2,Seg_Table[2]);
showsmg(7,Seg_Table[tempset / 10]);
showsmg(8,Seg_Table[tempset % 10]);
}
}
//***********************************工厂模式
void factory01(){//校准值设置
showsmg(1,Seg_Table[15]);
showsmg(2,Seg_Table[1]);
if((disjiao & 0x80) == 0){
showsmg(8,Seg_Table[disjiao % 10]);
if(disjiao > 9){
showsmg(7,Seg_Table[disjiao / 10 % 10]);
}
}else{
showsmg(8,Seg_Table[~(disjiao - 1) % 10]);
if((disjiao < 0) && (disjiao > -9))
showsmg(7,Seg_Table[16]);
if(disjiao < -9){
showsmg(7,Seg_Table[~(disjiao - 1) / 10 % 10]);
showsmg(6,Seg_Table[16]);
}
}
}
void jiezhi(){//介质设置
showsmg(1,Seg_Table[15]);
showsmg(2,Seg_Table[2]);
showsmg(6,Seg_Table[v / 100]);
showsmg(7,Seg_Table[v / 10 % 10]);
showsmg(8,Seg_Table[v % 10]);
}
void factory03(){//DAC输出设置
showsmg(1,Seg_Table[15]);
showsmg(2,Seg_Table[3]);
showsmg(7,Seg_Table[dac / 10] & 0x7f);
showsmg(8,Seg_Table[dac % 10]);
}
//***********************************
//***********************************显示选择
void factoryselect(){
switch(factory){
case 0:factory01();break;
case 1:jiezhi();break;
case 2 :factory03();break;
}
}
void showselect(){
switch(mode){
case 0:
if(ce == 0){cewen();ceju();}
showdistemp();
break;
case 1:showset();break;
case 2:factoryselect();break;
}
}
//***********************************
//***********************************长短按检测定时器
void led();
void Timer0_Isr(void) interrupt 1
{
count_s++;
if(count_s >= 10){
flag = ~flag;
count_s = 0;
}
if(shuangan){
count++;
}
if(jilu == 1){
count2++;
}
if(count2 >= 600){
jilu = 0;
count2 = 0;
}
led();
}
void Timer0_Init(void) //10毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0xDC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
//***********************************
//***********************************按键扫描
void scankey(){
// unsigned char i;
if(jilu == 0){
P44 = 0;P42 = 1;
P33 = 1;P32 = 1;
if(P33 == 0){//S4
Delay(dt);
canshu = 0;
factory = 0;
if(mode == 2){Delay(dt);Delay(2*dt);}
mode++;
if(mode > 2){mode = 0;}
Delay(dt);Delay(2*dt);
while(P33 == 0){
showselect();
}
}
if(P32 == 0){//S5
Delay(dt);
if(mode == 0){unit = ~unit;}
if(mode == 1){canshu = ~canshu;}
if(mode == 2){factory++;factory %= 3;}
while(P32 == 0){
showselect();
}
}
P44 = 1;P42 = 0;
P33 = 1;P32 = 1;
if(P33 == 0){//S8
Delay(dt);
while(P33 == 0){
if(P32 == 0){//S8按下同时是否有S9按下
Delay(dt);
shuangan = 1;
while((P33 == 0) && (P32 == 0)){
showselect();
}
shuangan = 0;
}
showselect();
}
if((count <= 200)){//短按为
if((mode == 1) && (canshu == 0)){//距离参数加按键
disset = disset + 10;
if(disset == 100){
disset = 10;
}
}
if((mode == 1) && (canshu == 1)){//距离参数加按键
tempset = tempset + 1;
if(tempset == 80){
tempset = 0;
}
}
if(mode == 0){//记录模式
jilu = 1;
n = 0;
}
if((mode == 2) && (factory == 0)){//校准值模式加键
disjiao = disjiao + 5;
if(disjiao == 95){disjiao = 0;}
}
if((mode == 2) && (factory == 1)){//介质设置模式加键
v = v + 10;
if(v == 10000){v = 10;}
}
if((mode == 2) && (factory == 2)){//DAC下限加
dac = dac + 1;
if(dac == 21){dac = 1;}
}
count = 0;
}
if(count > 200){
mode = 0;//模式代号
unit = 0;//单位选择
canshu = 0;//参数选择
ce = 0;
set = 0;//设置选择
distance = 0;//距离
time = 0;//超神波时间
v = 340;//介质声速
temp = 0;//温度
n = 0;
temprec[n] = 0;
disrec[n] = 0;
disset = 40;//距离参数
tempset = 30;//温度参数
shuangan = 0;//按键是否都按下
count = 0;//计时
shuchu = 0;
jilu = 0;
count2 = 0;
factory = 0;
disjiao = 0;//距离校准值
dac = 10;
count = 0;
}
}
if(P32 == 0){//S9
Delay(dt);
while(P32 == 0){
if(P33 == 0){//S9按下同时是否有S8按下
Delay(dt);
shuangan = 1;
while((P33 == 0) && (P32 == 0)){
showselect();
}
shuangan = 0;
}
showselect();
}
if((count <= 200)){//短按为
if((mode == 1) && (canshu == 0)){//距离参数减按键
disset = disset - 10;
if(disset == 0){
disset = 90;
}
}
if((mode == 1) && (canshu == 1)){//距离参数减按键
tempset = tempset - 1;
if(tempset < 0){
tempset = 80;
}
}
if(mode == 0){//输出模式
shuchu = 1;
}
if((mode == 2) && (factory == 0)){//校准值模式加键
disjiao = disjiao - 5;
if(disjiao == -95){disjiao = 0;}
}
if((mode == 2) && (factory == 1)){//介质设置模式加键
v = v - 10;
if(v == 0){v = 9990;}
}
if((mode == 2) && (factory == 2)){//DAC下限加
dac = dac - 1;
if(dac == 0){dac = 20;}
}
count = 0;
}
if(count > 200){
count = 0;
mode = 0;//模式代号
unit = 0;//单位选择
canshu = 0;//参数选择
ce = 0;
set = 0;//设置选择
distance = 0;//距离
time = 0;//超神波时间
v = 340;//介质声速
temp = 0;//温度
n = 0;
temprec[n] = 0;
disrec[n] = 0;
disset = 40;//距离参数
tempset = 30;//温度参数
shuangan = 0;//按键是否都按下
count = 0;//计时
shuchu = 0;
jilu = 0;
count2 = 0;
factory = 0;
disjiao = 0;//距离校准值
dac = 10;
}
}
}
}
//***********************************
//***********************************LED
void led(){
switch(mode){
case 0:
ledstat = distance;
if(distance > 255){
ledstat = 0x00;
}
outputp0(4,~ledstat);
break;
case 1:ledstat = 0x7f;outputp0(4,ledstat);;break;
case 2:if(flag){ledstat = 0xfe;}else{ledstat = 0xff;}outputp0(4,ledstat);break;
}
}
//***********************************
//***********************************继电器
//***********************************
void main(){
unsigned char tmp = 0;
Timer0_Init();
initsys();
while(1){
scankey();
showselect();
tmp = (5-dac)*(disrec[n] - 10);
tmp = ((tmp/ 80)+dac) * 51;
if(shuchu == 1){
DAC(tmp);
}
led();
if((distance >= (disset-5)) && (distance <= (disset+5)) && temp <= tempset*10){
outputp0(5,0x10);
}else{
outputp0(5,0x00);
}
}
}
BUG:DAC没做好,直线方程用点斜式没算准