#include <STC15F2K60S2.H>
#include <Intrins.H>
sbit I2C_SCL=P2^0;
sbit I2C_SDA=P2^1;
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n–);
}
void I2C_Start()
{
I2C_SDA = 1;
I2C_Delay(1);
I2C_SCL = 1;
I2C_Delay(1); // 起始条件建立时间
I2C_SDA = 0;
I2C_Delay(1); // 起始条件保持时间
I2C_SCL = 0;
I2C_Delay(1);
}
void I2C_End()
{
I2C_SDA = 0;
I2C_Delay(1);
I2C_SCL = 1;
I2C_Delay(1); // 停止条件建立时间
I2C_SDA = 1;
I2C_Delay(1); // 总线空闲时间
}
void I2C_Sendbyte(unsigned char byte)
{
unsigned char i = 0;
for(i = 0; i < 8; i++)
{
I2C_SDA = byte & (0x80 >> i);
I2C_Delay(1); // 数据建立时间
I2C_SCL = 1;
I2C_Delay(1); // 时钟高电平时间
I2C_SCL = 0;
I2C_Delay(1); // 数据保持时间
}
}
unsigned char I2C_receivebyte()
{
unsigned char Recievebyte = 0x00;
unsigned char byte = 0x80;
unsigned char i = 0;
I2C_SDA = 1;
I2C_Delay(1);
for(i = 0; i < 8; i++)
{
I2C_Delay(1); // 数据建立时间
I2C_SCL = 1;
I2C_Delay(1); // 时钟高电平时间(采样数据)
if(I2C_SDA)
{
Recievebyte |= (byte >> i);
I2C_Delay(1);
}
I2C_SCL = 0;
I2C_Delay(1); // 数据保持时间
}
return Recievebyte;
}
void I2C_SendAckbyte(unsigned char Ackbyte)
{
I2C_SDA = Ackbyte;
I2C_Delay(1); // 应答位建立时间
I2C_SCL = 1;
I2C_Delay(1); // 时钟高电平时间
I2C_SCL = 0;
I2C_Delay(1); // 应答位保持时间
}
unsigned char I2C_receiveAckbyte()
{
unsigned char RecieveAckbyte;
I2C_SDA = 1; // 释放SDA,让从机控制
I2C_Delay(1); // 建立时间
I2C_SCL = 1;
I2C_Delay(1); // 时钟高电平时间(采样应答)
RecieveAckbyte = I2C_SDA;
I2C_Delay(1);
I2C_SCL = 0;
I2C_Delay(1); // 保持时间
return RecieveAckbyte;
}
#include <STC15F2K60S2.H>
#include <I2C.H>
unsigned char r_adc(unsigned char addr){
unsigned char date;
EA=0;
I2C_Start();
I2C_Sendbyte(0x90);
I2C_receiveAckbyte();
I2C_Sendbyte(addr);
I2C_receiveAckbyte();
I2C_Start();
I2C_Sendbyte(0x91);
I2C_receiveAckbyte();
date=I2C_receivebyte();
I2C_SendAckbyte(1);
I2C_End();
EA=1;
return date;
}
#include <STC15F2K60S2.H>
void Timer0_Init()
{
AUXR |= 0x80; // 定时器时钟1T模式
TMOD &= 0xF0; // 设置定时器模式
TL0 = 0x50; // 设置定时初始值 100微秒
TH0 = 0xFB; // 设置定时初始值
TF0 = 0; // 清除TF0标志
TR0 = 1; // 定时器0开始计时
ET0 = 1; // 使能定时器0中断
EA = 1; // 开启总中断
}
#include <STC15F2K60S2.H>
#include “Delay.h”
void HC573_Select(unsigned char Channal)
{
P2=(P2&0x1F)|(Channal<<5);
}
void HC573_Init()
{
HC573_Select(4);
P0=0xFF;
HC573_Select(5);
P0=0xFF;
HC573_Select(6);
P0=0x0F;
HC573_Select(7);
P0=0xFF;
Delay_ms(20);
}
#include <STC15F2K60S2.H>
#include “HC573.H”
#include “PCF8951.H”
#include “Timer0.H”
unsigned int voltage;
static unsigned int Count1=0;
static unsigned int Count2=0;
float ADC_Number;
unsigned char Temp;
unsigned char ADC_Flag;
unsigned char Buffer_Flag;
unsigned char Seg_Buff[8] = {11,11,11,11,11,11,11,11}; // 初始消隐
// 段码表添加U和消隐字符
unsigned char code Nixie_NumberS[] = {
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90, // 9
0xC1, // U (10)
0xFF // 消隐 (11)
};
unsigned char code Nixie_LocationS[] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};
void Nixie_UpDate()
{
unsigned int voltage = (unsigned int)(ADC_Number * 100); // 转换为整数
Seg_Buff[7] = voltage % 10; // 百分位
Seg_Buff[6] = voltage % 100 / 10; // 十分位
Seg_Buff[5] = voltage / 100; // 个位(带小数点)
Seg_Buff[4] = 10; // 显示”U”
Seg_Buff[3] = 11; // 消隐
Seg_Buff[2] = 11; // 消隐
Seg_Buff[1] = 11; // 消隐
Seg_Buff[0] = 11; // 消隐
}
// 修复数码管扫描函数
void Nixie_Scan(unsigned char Location, unsigned char Number)
{
P0 = 0xFF;
HC573_Select(6);
P0 = Nixie_LocationS[Location];
HC573_Select(7);
P0 = Nixie_NumberS[Number];
// 在位置5(个位)显示小数点
if(Location == 5) {
P0 &= 0x7F; // 添加小数点
}
}
void Nixie_Loop()
{
static unsigned char i = 0;
Nixie_Scan(i, Seg_Buff[i]);
i++;
if(i >= 8) { i = 0; } // 扫描所有8个数码管
}
void main()
{
unsigned char temp;
HC573_Init();
Timer0_Init();
while(1)
{
if(ADC_Flag)
{
ADC_Flag = 0;
temp = r_adc(3);
ADC_Number = (float)temp / 255 * 5.0;
Nixie_UpDate();
}
if(Buffer_Flag)
{
Buffer_Flag = 0;
Nixie_Loop();
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned char count1 = 0;
static unsigned int count2 = 0;
count1++;
count2++;
if(count1 == 2) { // 200微秒扫描数码管
Buffer_Flag = 1;
count1 = 0;
}
if(count2 == 1000) { // 100毫秒读取ADC
ADC_Flag = 1;
count2 = 0;
}
}