前言
HC89S003F4 是一颗采用高速低功耗 CMOS 工艺设计开发的增强型 8 位单片机,内部有 16K Bytes FLASH 程序存储器, 256 Bytes IRAM 和 256 Bytes XRAM ,最多 18 个双向 I/O 口, 1 个外设功能引脚全 映射模块 PTM ,5 个 16 位定时器 / 计数器,3 组 12 位带死区控制互补 PWM ,1 个 8 位 PWM ,2 个 UART , 1 个 SPI , 16 个外部中断, 11+2 路 12 位 ADC ,四种系统工作模式(正常、低频、掉电和空闲)和 16 个中断源。
1.延时函数
代码如下(示例):
#define ALLOCATE_EXTERN
#include "HC89S003F4.h"
sbit KEY = P2^7;
sbit LED = P0^0;
#define N_KEY 0
#define S_KEY 1
#define D_KEY 2
#define L_KEY 10
#define MOTO_ON() PWM0DH = 0x01; PWM0DL = 0xF4;
#define MOTO_OFF() PWM0DH = 0x00; PWM0DL = 0x00;
bit FlagSysClk10ms; //10ms标记位
bit FlagSysClk500ms; //500ms标记位
unsigned char KeyValue = 0;
unsigned char CntSysClk10ms = 0; //时钟10MS记数
unsigned char CntSysClk500ms = 0; //时钟500MS记数
unsigned int Bat_Adc = 0; //电池电量
/***************************************************************************************
*延时函数*
***************************************************************************************/
void Delay_2us(unsigned int fui_i) //2us延时
{
while(fui_i--);
}
void Delay_ms(unsigned int fui_i) //1ms延时
{
unsigned int fui_j;
for(;fui_i > 0;fui_i --)
for(fui_j = 1596;fui_j > 0;fui_j --);
}
2.TIM0时钟配置1ms计时
代码如下(示例):
/*********************************TIM0时钟配置初始化************************************/
void Timer0_init(void)
{
TCON1 = 0x00; //Tx0定时器时钟为Fosc
TMOD = 0x00; //16位重装载定时器/计数器
//Tim0计算时间 = (65536 - 0xFACB) * (1 / (Fosc /Timer分频系数)) = 1333 / (16000000 / 12) = 1 ms
//定时1ms 反推初值 = 65536 - ((1/1000) / (1/(Fosc / Timer分频系数)))
// = 65536 - ((1/1000) / (1/(16000000 / 12))) = 65536 - 1333 = 0xFACB
TH0 = 0xFA;
TL0 = 0xCB; //T0定时时间1ms
IE |= 0x02; //打开T0中断
TCON |= 0x10; //使能T0
EA = 1; //打开总中断
}
2.PWM0配置2Hz频率,产生50%占空比
/*************************************PWM0初始化****************************************/
void PWM_init(void)
{
P2M1 = P2M1&0xF0|0x08; //P22设置为推挽输出
P1M0 = P1M0&0xF0|0x08; //P10设置为推挽输出
PWM0_MAP = 0x07; //PWM0通道映射P07口
PWM01_MAP = 0x10; //PWM01通道映射P10口
PWM0C = 0x01; //PWM0、PWM01高有效,时钟8分频
//独立模式下,PWM0和PWM01共用一个周期寄存器
//周期计算 = 0x03E8 / (Fosc / PWM分频系数) = 0x03E8 / (16000000 / 8) = 500us / 2kHz
PWM0PH = 0x03;
PWM0PL = 0xE8;
//占空比计算= 0x0155 / (Fosc / PWM分频系数)
// = 0x01F4 / (16000000 / 8) = 500 / 2000000 = 250us 占空比为250/500 = 50%
PWM0DH = 0x01; //PWM0高4位
PWM0DL = 0xF4; //PWM0低8位
PWM0DTH = 0x01; //PWM01高4位
PWM0DTL = 0xF4; //PWM01低8位
PWM0EN = 0x0F; //使能PWM0,工作于独立模式
}
3.按键扫描状态
unsigned char key_driver(void)
{
static unsigned char key_state = 0; // 按键状态变量
static unsigned int key_time = 0; // 按键计时变量
unsigned char key_return;
key_return = N_KEY; // 清除 返回按键值
switch (key_state)
{
case 0: // 按键状态0按键按下
if (!KEY) key_state = 1; // 有按键按下
break;
case 1: // 按键状态1:软件消抖。按键有效的定义:按键持续按下超过设定的消抖时间。
if (!KEY)
{
key_time = 0; // 一次10ms
key_state = 2; // 进入 按键状态2, 继续判定到底是那种有效按键
}
else key_state = 0; // 如果按键时间没有超过,判定为误触,按键无效,返回 按键状态0,继续等待按键
break;
case 2: // 按键状态2:判定按键有效的种类:是单击,还是长按
if(KEY)
{
key_return = S_KEY; // 返回 有效按键值:单击
key_state = 0; // 返回 按键状态0,继续等待按键
}
else
{
key_time++;
if(key_time >= 200) // 如果按键时间超过2s, 则判定为 长按
{
key_return = L_KEY; // 返回 有效键值值:长按
key_state = 3; // 去状态3,等待按键释放
}
}
break;
case 3: // 等待按键释放
if (KEY) key_state = 0;
break;
default:
key_state = 0;
break;
}
return key_return; // 返回 按键值
}
3.main函数
void main()
{
System_init();
Timer0_init();
PWM_init();
//ADC_init();
LED = 1;
while(1)
{
if(FlagSysClk10ms)
{
FlagSysClk10ms = 0;
KeyValue = key_driver();
switch(KeyValue)
{
case S_KEY:
LED = ~LED;
MOTO_OFF();
break;
case L_KEY:
LED = 0;
MOTO_ON();
break;
}
}
if(FlagSysClk500ms)
{
FlagSysClk500ms=0;
ADCC0 |= 0x40; //启动ADC转换
while(!(ADCC0&0x20)); //等待ADC转换结束
ADCC0 &=~ 0x20; //清除标志位
Bat_Adc = ADCR;
if(Bat_Adc < 2048)
{
LED = 0;
}
else LED = 1;
}
}
}
该处使用的url网络请求的数据。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_40074141/article/details/120100083
|