不断更新
锁存器、晶体管显示驱动代码、延时函数
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<