[通用8051核FLASH系列]

芯圣HC89S003F4简单测试代码

[复制链接]
1346|10
手机看帖
扫描二维码
随时随地手机跟帖
qn7a12|  楼主 | 2022-11-26 16:22 | 显示全部楼层 |阅读模式
本帖最后由 芯圣电子官方QQ 于 2023-7-25 11:05 编辑

前言
       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 个中断源。


延时函数 代码如下(示例):
#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 --);
}







使用特权

评论回复
qn7a12|  楼主 | 2022-11-26 19:10 | 显示全部楼层
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;                                    //打开总中断
}

使用特权

评论回复
qn7a12|  楼主 | 2022-11-26 19:13 | 显示全部楼层
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,工作于独立模式
}

使用特权

评论回复
qn7a12|  楼主 | 2022-11-26 19:14 | 显示全部楼层
按键扫描状态
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;                          // 返回 按键值
}

使用特权

评论回复
qn7a12|  楼主 | 2022-11-26 19:16 | 显示全部楼层
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;
        }
    }
}

使用特权

评论回复
tpgf| | 2022-12-7 14:10 | 显示全部楼层
一般说一个芯片是高速芯片 是说其主频高吗

使用特权

评论回复
磨砂| | 2022-12-7 14:32 | 显示全部楼层
看代码应该是在主函数中进行的轮询吧

使用特权

评论回复
晓伍| | 2022-12-7 14:42 | 显示全部楼层
FlagSysClk10ms这个标志位应该是用来判定是否到时的吧 在哪里进行计时的呢

使用特权

评论回复
八层楼| | 2022-12-7 15:08 | 显示全部楼层
按键扫描状态 函数的调用没有体现出来呀

使用特权

评论回复
观海| | 2022-12-7 15:27 | 显示全部楼层
既然初始化为pwm模式了 为什么还在主函数里边判断呢

使用特权

评论回复
guanjiaer| | 2022-12-7 15:51 | 显示全部楼层
感觉楼主主函数的操作和外设模块的初始化不匹配

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

402

帖子

0

粉丝