用ad0832 电压改变实现对转速的控制
测转速利用定时器0+计数器
将测得的转速与输入值相比较 如果转速小于输入值电压增大 反之则减小电压。
具体代码如下
// 文件名:
// 功能:
// 输入参数:
// 功能: cs0--keyledcs cs2--dacs
// 出口函数:
#include<reg51.h>
xdata unsigned char OUTBIT _at_ 0x8002; // 位控制口
xdata unsigned char OUTSEG _at_ 0x8004; // 段控制口
xdata unsigned char IN _at_ 0x8001; // 键盘读入口
unsigned char LEDBuf[6]; // 显示缓冲
unsigned int Keyval[3]; // 显示缓冲
code unsigned char KeyTable[] = { // 键码定义
0x16, 0x15, 0x14, 0xff,
0x13, 0x12, 0x11, 0x10,
0x0d, 0x0c, 0x0b, 0x0a,
0x0e, 0x03, 0x06, 0x09,
0x0f, 0x02, 0x05, 0x08,
0x00, 0x01, 0x04, 0x07
};
code unsigned char LEDMAP[] = { // 八段管显示码
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
#define Tick 10000 // 10000 x 100us = 1s
#define T100us (256-50) // 100us时间常数(6M)
unsigned int C100us; // 100us记数单元
unsigned int count; // 频率记数单元
xdata unsigned char CS0832 _at_ 0xa000; //DAC
unsigned int speedval; // 转速控制字
//########################################
//延时
//########################################
void delay(unsigned char CNT)
{
unsigned char i;
while (CNT-- !=0)
for (i=10; i !=0; i--);
}
//########################################
//初始化LED
//########################################
void InitLED()
{
unsigned char i;
unsigned char Pos;
unsigned char LED;
LEDBuf[0] = 0x7f; // 初始化检测显示的值
LEDBuf[1] = 0x7f;
LEDBuf[2] = 0x7f;
LEDBuf[3] = 0x7f;
LEDBuf[4] = 0x7f;
LEDBuf[5] = 0x7f;
Pos = 0x20; // 检测LED,从左边开始扫描显示
for (i = 0; i < 6; i++) {
OUTBIT = 0; // 关所有八段管
OUTBIT = Pos; // 显示一位八段管
LED = LEDBuf[i];
OUTSEG = LED;
Pos >>= 1; // 显示下一位
delay(100);
}
}
//########################################
//LED显示程序
//########################################
void DisplayLED()
{
unsigned char i;
unsigned char Pos;
unsigned char LED;
Pos = 0x20; // 从左边开始显示
for (i = 0; i < 6; i++) {
LED = LEDBuf[i];
OUTSEG = LED;
OUTBIT = Pos; // 显示一位八段管
Pos >>= 1; // 显示下一位
delay(1);
}
}
//########################################
//Key检测
//########################################
unsigned char TestKey()
{
OUTBIT = 0; // 输出线置为0
return (~IN & 0x0f); // 读入键状态(高四位不用)
}
unsigned char GetKey()
{
unsigned char Pos;
unsigned char i;
unsigned char k;
i = 6;
Pos = 0x20; // 找出键所在列
do {
OUTBIT = ~ Pos;
Pos >>= 1;
k = ~IN & 0x0f;
} while ((--i != 0) && (k == 0));
// 键值 = 列 x 4 + 行
if (k != 0) {
i *= 4;
if (k & 2)
i += 1;
else if (k & 4)
i += 2;
else if (k & 8)
i += 3;
OUTBIT = 0;
do DisplayLED(); while (TestKey());
return(KeyTable[i]); // 取出键码
} else return(0xff);
}
//########################################
// 将 Number 拆为三个 BCD 码, 并存入 Result 数组
//########################################
void BCD(int Number)
{
LEDBuf[3] = LEDMAP[Number / 100]; // 数除以 100, 得百位数
LEDBuf[4] = LEDMAP[(Number % 100) / 10]; // 余数除以 10, 得十位数
LEDBuf[5] = LEDMAP[ Number % 10 ]; // 数除以 10, 余数得个位数
}
//########################################
//定时器中断
//########################################
void T0Int() interrupt 1
{
C100us--;
if (C100us == 0)
{
C100us = Tick; // 100us 记数器为0, 重置记数器
count=TH1;
count=(count<<8)+TL1;
TH1 = 0;
TL1 = 0;
BCD(count);
}
}
//########################################
//速度检测
//########################################
void chesu_Init()
{
TMOD = 0x52; // T0方式1,记数器;T1方式1,记数器
TH1 = 0;
TL1 = 0;
TH0 = T100us;
TL0 = T100us;
IE = 0x82; // EA=1, IT0 = 1
C100us = Tick;
TR0 = 1; // 开始定时
TR1 = 1; // 开始记数 // 方式2, 定时器
}
//########################################
//主程序
//########################################
void main()
{
unsigned char i;
speedval = 160;
InitLED();
chesu_Init();
while (1)
{
if (TestKey())
{
Keyval[i] = GetKey() & 0x0f;
LEDBuf[i] = LEDMAP[Keyval[i]];
if ( i < 2 ) i++;
else i=0;
}
if ((Keyval[1]*10 + Keyval[2]) > count)
{ if (speedval < 255) speedval++; }
else if ((Keyval[1]*10 + Keyval[2]) < count)
{ if (speedval > 128) speedval--; }
else speedval=speedval ;
CS0832 = speedval;
DisplayLED();
}
}
|