打印
[其它]

合泰 HT66F018 编程介绍

[复制链接]
3015|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
欢乐家园|  楼主 | 2022-11-17 14:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 eltonchang2001 于 2022-11-17 15:04 编辑

HT-IDE3000的使用

详细的HT-IDE3000使用手册可以在HT-IDE3000中直接打开:帮助->Holtek HT-IDE3000使用手册。
模块解析

HT66F018的数据手册可在Holtek官网自行下载,也可点击此处下载。
1. 时钟配置

工程创建好之后,通过:工具->配置选项,可对系统的工作电压、时钟源、频率等进行修改。
本例程的配置:

    SysVolt = 5.0V;
    Vdd = 5.0V;
    OSC = internal RC + IO1/IO2; (使用内部RC)
    HIRC = 8MHz;
    fsub clock = LIRC;

SMOD寄存器在上电复位后的初始值为0000 0011,本程序不再对其修改,故最终的时钟是使用内部高速时钟:8MHz。该寄存器的详细信息在datasheet中工作模式和系统时钟一节。


使用特权

评论回复
评论
欢乐家园 2022-11-17 15:38 回复TA
———————————————— 版权声明:本文为CSDN博主「freeze chen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/crazy_kismet/article/details/85276497 

相关帖子

沙发
欢乐家园|  楼主 | 2022-11-17 15:01 | 只看该作者
端口配置

端口配置不外乎输入/输出模式的选择,以及上拉电阻的配置。合泰的头文件HT66F018.h中,所有寄存器都是以“_”开头,使用小写字母。

    每一个输入/ 输出口都具有各自的控制寄存器,即PAC~PCC,用来控制输入/输出状态:0–输出,1–输入;上电复位后默认为输入模式;
    上拉电阻可通过寄存器PAPU~PCPU 来设置,它用一个PMOS 晶体管来实现上拉电阻功能:0–不上拉,1–上拉;
    PA 口唤醒:单片机进入休眠或空闲模式后,。唤醒单片机有很多种方法,其中之一就是使 PA 口的其中一个引脚从高电平转为低电平。PA 口的每个引脚可以通过设置PAWU 寄存器来单独选择是否具有唤醒功能:0–不使能,1使能;

使用特权

评论回复
板凳
欢乐家园|  楼主 | 2022-11-17 15:02 | 只看该作者
    _acerl = 0; //disable all AD
       
        //PA口配置
    _pac = 0x68;    //0110 1000
    _papu = 0x08;   //0000 1000
    _pa = 0x04;     //0000 0100
    _pawu = 0x0;    //禁止PA唤醒功能

    //PB口配置
    _pbc = 0x07;    //0000 0111
    _pbpu = 0x00;
    _pb = 0x00;
       
    //PA0口拉高
    _pa0 = 1;

    //判断PA3口的端口电平状态
    if (0 == _pa3)

使用特权

评论回复
地板
欢乐家园|  楼主 | 2022-11-17 15:03 | 只看该作者
A/D 转换控制寄存器的上电初始状态默认PA4-PA7, PB0-PB3 为模拟信号输入引脚,但A/D 转换功能并没自动开启。因些需注意若要将PA4-PA7, PB0-PB3用作数字信号输入引脚,或其它功能,需在程序中修改A/D 转换控制寄存器值以关闭A/D 功能。另外需注意A/D 通道使能,内部上拉电阻将自动断开。

使用特权

评论回复
5
欢乐家园|  楼主 | 2022-11-17 15:04 | 只看该作者
定时器

HT66F018包含3 个TM, 分别命名为TM0,TM1 和TM2。每个TM 可被划分为一个特定的类型,即简易型TM(CTM),标准型TM(STM) 或周期型TM(PTM)。

使用特权

评论回复
6
欢乐家园|  楼主 | 2022-11-17 15:05 | 只看该作者
下面提供使用TM0定时1ms,TM1定时200us的配置代码:

    _cpc = 0x08;    //关比较器
    _tmpc = 0;  //禁止TMn输入/输出引脚

    _tm0c0 = 0x00; //TM0时钟为系统时钟4分频(Fsys=8M),则TM0时钟为2M,并关闭定时器
    _tm0c1 = 0xC1;  //定时/计数器模式模式,比较器A匹配(即16位比较)
    _tm0al = 0xD0;  //定时器T0赋初值,定时1ms
    _tm0ah = 0x07;

    _tm1c0 = 0x00;  //TM1时钟为系统时钟4分频(Fsys=8M),则TM1时钟为2M,并关闭定时器
    _tm1c1 = 0xC1;  //1100 0001 定时器模式,比较器A匹配
    _tm1al = 0x90;
    _tm1ah = 0x01;  //定时器T1赋初值,定时200us

使用特权

评论回复
7
欢乐家园|  楼主 | 2022-11-17 15:09 | 只看该作者
简易型TM 核心是一个由用户选择的内部或外部时钟源驱动的16 位向上计数器,它还包括两个内部比较器即比较器A 和比较器P。这两个比较器将计数器的值与CCRP 和CCRA 寄存器中的值进行比较。CCRP 是8 位的,与计数器的高8 位比较;而CCRA 是16 位的,与计数器的所有位比较。

使用特权

评论回复
8
欢乐家园|  楼主 | 2022-11-17 15:11 | 只看该作者
定时器的功能比较复杂,其他模式的配置请自行参见datasheet中的介绍。

使用特权

评论回复
9
欢乐家园|  楼主 | 2022-11-17 15:12 | 只看该作者
中断使能

HT66F018提供多个外部中断和内部中断功能,外部中断由INT0~INT1 引脚动作产生,而内部中断由各种内部功能,如定时器模块、比较器、时基、LVD、EEPROM 和A/D 转换器等产生。

使用特权

评论回复
10
欢乐家园|  楼主 | 2022-11-17 15:13 | 只看该作者
下面提供的代码接上一节定期器的内容,使能定时器T0和T1的中断,同时打开外部中断0:

    _integ = 0x03;      //外部INT0中断双沿控制
    _intc0 = 0x08;      //使能外部中断0,使能多功能中断0(其中包括TM0定时)
    _intc1 = 0x01;      //使能多功能中断1(即使能TM1中断)

    _intc2 = 0x00;      //禁止其它中断

    _mfi0 = 0x02;       //TM0比较匹配A中断使能
    _mfi1 = 0x02;       //TM1比较匹配A中断使能
    _mfi2 = 0x00;       //禁止其它中断

    _emi = 1;   //开总中断
    _t0on = 1;  //启动定时器0
    _t1on = 1;  //启动定时器1
    _int0e = 1; //使能外部中断0

使用特权

评论回复
11
欢乐家园|  楼主 | 2022-11-17 15:15 | 只看该作者
通过禁止相关中断使能位,可以屏蔽中断请求,然而,一旦中断请求标志位被设定,它们会被保留在中断控制寄存器内,直到相应的中断服务子程序执行或请求标志位被软件指令清除。
多功能中断中所含中断相应程序执行时,多功能中断请求标志MF0F-MF2F 可以自动清零,但各自的请求标志需在应用程序中手动清除。

使用特权

评论回复
12
欢乐家园|  楼主 | 2022-11-17 15:32 | 只看该作者
中断函数编写

如下图展示的是HT66F018的中断结构图,可以在datasheet的Page117中找到,在编写中断函数时,主要需要用到下图中的*Vector(中断向量)*一列。各个中断使能位以及相应的请求标志位,以优先级的次序显示在下图。一些中断源有自己的向量,但是有些中断却共用多功能中断向量。

使用特权

评论回复
13
欢乐家园|  楼主 | 2022-11-17 15:33 | 只看该作者

使用特权

评论回复
14
欢乐家园|  楼主 | 2022-11-17 15:35 | 只看该作者
/* timer0 interrupt, 1ms */
void __attribute((interrupt(0x0C))) timer0(void)
{
    _t0af = 0;        //清除T0中断标志位
       
    //user code start
    //...
    //user code end

    /* 一旦中断子程序被响应,系统将自动清除EMI位,所有其它的中断将被屏蔽 */
    _emi = 1;   //手动打开总中断
}
/* timer1 interrupt, 200us */
void __attribute((interrupt(0x10))) timer1(void)
{
    _t1af = 0;
       
    //user code start
    //...
    //user code end

    /* 一旦中断子程序被响应,系统将自动清除EMI位,所有其它的中断将被屏蔽 */
    _emi = 1;   //手动打开总中断
}
/* int0 *、
void __attribute((interrupt(0x04))) Int0(void)
{
    //不需要清除中断标志位
       
    _emi = 1;   //手动打开总中断
}

使用特权

评论回复
15
欢乐家园|  楼主 | 2022-11-17 15:36 | 只看该作者
一旦中断子程序被响应,系统将自动清除EMI位,所有其它的中断将被屏蔽,这个方式可以防止任何进一步的中断嵌套。其它中断请求可能发生在此期间,虽然中断不会立即响应,但是中断请求标志位会被记录。

使用特权

评论回复
16
欢乐家园|  楼主 | 2022-11-17 15:38 | 只看该作者
ADC

HT66F018包含一个多通道的A/D转换器,它们可以直接接入外部模拟信号(来自传感器或其它控制信号)并直接将这些信号转换成12位的数字量。
转换流程如下:ADCR0 寄存器中的START 位,用于打开和复位A/D 转换器。当单片机设定此位从逻辑低到逻辑高,然后再到逻辑低,就会开始一个模数转换周期。当START 位从逻辑低到逻辑高,但不再回到逻辑低时,ADCR0 寄存器中的EOCB 位置“1”,复位模数转换器。START 位用于控制内部模数换转器的开启动作。ADCR0 寄存器中的EOCB 位用于表明模数转换过程的完成。在转换周期结束后,EOCB 位会被单片机自动地置为“0”。

使用特权

评论回复
17
欢乐家园|  楼主 | 2022-11-17 15:39 | 只看该作者
代码描述:
void adc_init()
{
    _adcr0 = 0x00;
    _adrfs = 0; //ADC 数据高字节是ADRH 的bit 3~bit 0,低字节是ADRL 的bit 7~bit 0
    _adcr1 = 0x03;      //设置AD参考为内部ADC电源,确定时钟为系统时钟8分频,即AD时钟周期为1us.
                        //AD转换时间为16个AD时钟周期。
    _acerl = 0x26;      //选择PA6/pb2/pb1为AD输入引脚(AN5/AN2/AN1)
}

/* 根据通道值获取ADC采样值 */
uint16_t GetAdResult(uint8_t adc_chan)
{
    uint16_t result;

    _adcr0 = adc_chan;

    _start = 0;
    _start = 1;
    _start = 0;

    while(_eocb);

        //_adrfs为0,使用下面数据格式拼接处结果
    result = (_adrh << 4) & 0xFF0;
    result = result | ((_adrl >> 4) & 0xF);

    return result;
}

使用特权

评论回复
18
欢乐家园|  楼主 | 2022-11-17 15:42 | 只看该作者
总结

HT66F018的编码总体来说还是比较简单的,只是存在不少的坑,比如中断服务中单片机会自动清除emi,这种情况我还是第一回碰到。最后要说的是,多读几遍datasheet是关键,很多编程的关键点在datasheet中都有说明;中文的datasheet,理解起来也比较快。

使用特权

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

本版积分规则

106

主题

941

帖子

1

粉丝