一、宏定义
#ifndef PUBLIC_H
#define PUBLIC_H
#include <STC15F2K60S2.H>
#include "intrins.h"
#define u8 unsigned char
#define u16 unsigned int
#endif
二、主函数:
#ifndef MAIN_H
#define MAIN_H
#include "Public.h"
#include "stdio.h"
#include "Device.h"
#include "Uart.h"
#include "string.h"
#include "iic.h"
//模式切换
u8 seg_mode; //0为噪声显示模式
char set_num;
u8 nose_sign;
u8 count_1ms;
//串口
char uart_temp[7];
u8 uart_temp1;
u8 r_sign,r_num;
u8 r_temp;
//数码管
u16 seg_delay;
u8 COT[10],COD[8],PSI;
//按键
u8 key_delay;
//LED
u8 l_data;
//PCF8591
float volt_num,nose;
#endif
// 40
#include "main.h"
void SEG_Proc();
void Key_Proc();
void Init();
void main()
{
All_Close();
UartInit();
Timer1Init();
Init();
while(1)
{
SEG_Proc();
Key_Proc();
}
}
void Uart_IT(void) interrupt 4
{
if(RI)
{
RI = 0;
if(uart_temp1 == 'R')
{
uart_temp[0] = 'R';
uart_temp[r_num] = SBUF;
if(++r_num == 6)
{
r_num = 0;
r_sign = 1;
uart_temp1 = 0;
}
}
else
{
uart_temp1 = SBUF;
r_num = 1;
}
}
}
void T1_IT() interrupt 3
{
if(++seg_delay == 500)seg_delay = 0;
if(++key_delay == 10)key_delay = 0;
SEG_Show(COD[PSI],PSI);
if(++PSI == 8)PSI = 0;
if(nose_sign)
{
if(++count_1ms == 101)
{
count_1ms = 0;
l_data ^= 0x80;
}
}
else
l_data &= ~0x80;
LED_Show(l_data);
}
void SEG_Proc()
{
u8 i;
if(seg_delay)return;
seg_delay = 1;
//噪声测量
volt_num = PCF8591_ADC()/255.0*5;
nose = volt_num*18;
//L8
if(nose>set_num)
{
//开始计数
count_1ms = 0;
nose_sign = 1;
}
else
nose_sign = 0;
//参数模式
if(seg_mode)
{
sprintf(COT,"U2 %2u",(u16)set_num);
}
else //显示模式
{
sprintf(COT,"U1 %4.1f",nose);
if(r_sign)
{
r_sign = 0;
if(strcmp(uart_temp,"Return") == 0)
printf("Noises:%4.1fdB\r\n",nose);
}
}
SEG_TSL(COT,COD);
}
void Key_Proc()
{
static u8 key_old;
u8 key_now,key_down;
if(key_delay)return;
key_delay = 1;
key_now = M_Key();
key_down = key_now & (key_now ^ key_old);
key_old = key_now;
//全模式
if(key_down == 12)
{
seg_mode = !seg_mode;
}
//参数模式
if(seg_mode)
{
if(key_down == 16)
{
set_num+=5;
if(set_num == 95)set_num = 0;
}
if(key_down == 17)
{
set_num-=5;
if(set_num == -5)set_num = 90;
}
}
//L1 L2
l_data = l_data & 0xfc | (0x01<<seg_mode);
}
void Init()
{
seg_mode = 0;
set_num = 65;
}
三、外设:
#ifndef DEVICE_H
#define DEVICE_H
#include "Public.h"
void All_Close();
void SEG_TSL(u8 *input,u8 *output);
void SEG_Show(u8 COD,u8 PSI);
void Timer1Init(void); //1毫秒@12MHz
u8 M_Key();
void LED_Show(u8 l_data);
#endif
#include "Device.h"
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
};
/*
关闭无关设备
*/
void All_Close()
{
//关闭蜂鸣器和继电器
P0 = 0x00;
P2 = P2 & 0x1f | (0x05<<5);
P2 &= 0x1f;
//关闭LED
P0 = 0xFF;
P2 = P2 & 0x1f | (0x04<<5);
P2 &= 0x1f;
//关闭数码管
P0 = 0xFF;
P2 = P2 & 0x1f | (0x07<<5);
P2 &= 0x1f;
}
/*
输入字符串,输出数码管代码
*/
void SEG_TSL(u8 *input,u8 *output)
{
u8 i=0,j=0;
for(i=0;i<8;i++,j++)
{
switch(input[j])
{
case '0':output[i] = Seg_Table[0];break;
case '1':output[i] = Seg_Table[1];break;
case '2':output[i] = Seg_Table[2];break;
case '3':output[i] = Seg_Table[3];break;
case '4':output[i] = Seg_Table[4];break;
case '5':output[i] = Seg_Table[5];break;
case '6':output[i] = Seg_Table[6];break;
case '7':output[i] = Seg_Table[7];break;
case '8':output[i] = Seg_Table[8];break;
case '9':output[i] = Seg_Table[9];break;
case 'U':output[i] = ~0x3e;break;
default:output[i] = 0xff;
}
if(input[j+1] == '.')
{
output[i] &= ~0x80;
j++;
}
}
}
/*
数码管显示函数
*/
void SEG_Show(u8 COD,u8 PSI)
{
//消隐
P0 = 0xff;
P2 = P2 & 0x1f | (0x07<<5);
P2 &= 0x1f;
//位选
P0 = 0x01<<PSI;
P2 = P2 & 0x1f | (0x06<<5);
P2 &= 0x1f;
//段选
P0 = COD;
P2 = P2 & 0x1f | (0x07<<5);
P2 &= 0x1f;
}
/*
定时器1
*/
void Timer1Init(void) //1毫秒@12MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初值
TH1 = 0xD1; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
EA = 1;
}
/*
矩阵按键按键检测
*/
u8 M_Key()
{
u16 key_temp=0;
u8 i=0;
//置0检测
P44=0;P42=1;P35=1;P34=1;
key_temp |= (P3 & 0x0f);
P44=1;P42=0;P35=1;P34=1;
key_temp = (key_temp<<4) | (P3 & 0x0f);
P44=1;P42=1;P35=0;P34=1;
key_temp = (key_temp<<4) | (P3 & 0x0f);
P44=1;P42=1;P35=1;P34=0;
key_temp = (key_temp<<4) | (P3 & 0x0f);
//对每一位进行0检测
for(i=0;i<16;i++)
if((key_temp & (0x8000>>i)) == 0)
return i+4;
return 0;
}
/*
LED显示函数,1为亮
*/
void LED_Show(u8 l_data)
{
P0 = ~l_data;
P2 = P2 & 0x1f | (0x04<<5);
P2 &= 0x1f;
}
四、串口:
#ifndef UART_H
#define UART_H
#include "Public.h"
#include "stdio.h"
void UartInit(void); //9600bps@12MHz
#endif
#include "Uart.h"
/*
初始化串口
*/
void UartInit(void) //9600bps@12MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xC7; //设定定时初值
T2H = 0xFE; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES = 1;
EA = 1;
}
/*
重定义printf为串口发送
*/
char putchar (char c)
{
SBUF = c;
while(!TI);
TI = 0;
return c;
}
五、IIC
#ifndef IIC_H
#define IIC_H
#include "Public.h"
sbit sda = P2^1;
sbit scl = P2^0;
u8 PCF8591_ADC();
void PCF8591_DAC(float volt);
#endif
#include "iic.h"
#define DELAY_TIME 5
//
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 I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
/*
读取RB2输出电压
*/
u8 PCF8591_ADC()
{
u8 adc_temp=0;
//选择PB2通道
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
//读取电压
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
adc_temp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return adc_temp;
}
/*
写入数据寄存器,输出相应的电压值
*/
void PCF8591_DAC(float volt)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CSendByte((u8)(volt*255/5));
I2CWaitAck();
I2CStop();
}