简介:面向中微CMS79FT738/736单片机的官方原版样例程序包,适合正在选型国产8位微控制器、需要快速掌握芯片初始化与外围模块开发的软硬件工程师。整套代码源自官方演示工程,按功能模块划分,覆盖LCD液晶显示、ADC模数转换、USART串口通信、EEPROM数据存储、定时器中断、外部中断、CCP脉宽调制、休眠节能等典型场景,并给出初始化流程、外设驱动、中断服务函数、低功耗模式切换等可直接套用的实现方法,寄存器配置清晰,便于对照数据手册理解底层逻辑。压缩包共342个文件,整体约719KB,文件类型以C源文件、汇编文件、编译生成的hex与bin固件、map内存映射、lst列表及工程配置文件为主,可支撑从源码阅读、编译烧录到调试分析的完整流程。已有3634人学习下载,既适合初次接触中微MCU的开发者对照示例逐模块学习,也能帮助资深工程师快速查证官方驱动细节、评估外围资源占用,提升项目落地效率。 搞单片机这些年,最怕的就是拿到一颗新芯片,手册翻完了,外设也看明白了,结果写第一行代码的时候还是心里没底。尤其是中微的CMS79FT738和CMS79FT736这类带触摸检测的8位机,官方样例程序的重要性比什么都大——它不仅是寄存器配置的参考答案,更直接决定了你触摸调校的起点。这次我把官方原版的样例程序整理出来了,给做家电触控、按键面板的同行们参考,省去大家找资料、试配置的弯路。
这篇内容我会把这颗芯片的资源、样例程序的完整结构、核心模块的代码逻辑,以及移植到实际项目时需要注意的细节一次讲清楚。如果你正准备用CMS79FT738/736做产品,或者刚刚接触中微的方案,这篇文章应该能帮你省下至少一周的摸索时间。
1. 先搞清楚CMS79FT738/736是什么定位
1.1 芯片资源概览
CMS79FT738和CMS79FT736是中微半导体推出的8位Flash型触摸单片机,主打家电触控面板这一块。两者的关系基本是同一个系列的容量和封装差异版本,738资源相对更充裕,736在引脚和存储上做了一些裁剪。选型的时候主要看按键通道数和IO需求,样机阶段建议直接上738,资源余量会大很多。
从底层架构来看,这系列芯片用的是RISC内核、精简指令集,主频不算高,但做触摸扫描和逻辑控制完全够用。内部集成Flash程序存储器和RAM,支持在线编程,这也意味着你可以通过烧录工装直接在产线上更新固件,不需要先拆下来换芯片。除此之外,芯片内部集成了触摸检测模块、多通道ADC、PWM输出、定时器、看门狗这些家电产品常用的外设。
我实测下来这块芯片的几个关键点:
- 触摸检测属于电荷转移方式,支持多通道扫描,灵敏度可以通过充放电时间和阈值来调节
- ADC位数应对NTC测温、电压检测这类场景绰绰有余
- PWM输出可以直驱蜂鸣器或者做LED调光,不需要额外加太多外围
- 工作电压范围比较宽,3.3V和5V系统都能用
1.2 典型应用场景
这种芯片在设计之初就瞄准了触摸按键类应用。最常见的就是电磁炉、电饭煲、热水器、油烟机这类厨房电器的控制面板,十几个触摸按键加LED/LCD显示、温度检测、蜂鸣器提示,一颗芯片全搞定。工业触控面板、小家电定时器、智能家居控制面板上也有大量应用。
我手里的这份官方样例程序,对应的正是这些场景的通用框架:触摸按键扫描、按键状态判断、蜂鸣器反馈、LED显示驱动、ADC采样、主循环任务调度,每个模块都分好了文件,移植的时候不需要推倒重来,改一改引脚和参数就能跑起来。
2. 官方样例程序完整结构解读
2.1 工程目录与核心文件
拿到官方原版样例程序后,先别急着打开编译。我建议先花十分钟把目录结构过一遍,理解每个文件的职责,后面移植的时候才知道该改哪里、不该改哪里。中微这套样例的工程结构大致是这样的:
CMS79FT738_Demo/ ├── Source/ │ ├── main.c # 主循环入口 │ ├── touch.c/h # 触摸扫描与按键处理 │ ├── adc.c/h # 模数转换 │ ├── pwm.c/h # PWM输出与蜂鸣器 │ ├── timer.c/h # 定时器 │ ├── led.c/h # LED数码管/指示灯 │ └── system.c/h # 时钟与系统初始化 ├── Lib/ │ └── TouchLib.lib # 官方触摸库 ├── Project/ │ └── *.uvproj # Keil工程文件(或中微IDE工程) └── Doc/ └── 使用说明.pdf可以看到官方对模块做了很好的切分,尤其是触摸这块,算法核心部分是封装成库的,对外开放的接口只有初始化、启动扫描、获取键值这几个函数。这种做法的好处是保护了核心算法,同时又给应用层留了足够多的可配置项。
2.2 模块间的调用关系
整个程序的运行流程可以归纳为:上电后先做系统时钟和IO初始化,然后初始化触摸模块,打开定时器产生节拍,主循环里不断查询触摸标志位,有按键事件就分发到相应的处理函数,同时ADC和PWM模块独立工作,互不阻塞。
这里有个值得注意的设计思路:官方采用“主循环+标志位”的协作式架构,而不是用中断嵌套。触摸扫描完成后在中断里置标志位,主循环里判断标志位再处理业务逻辑。这样可以避免在中断里做耗时操作,保证触摸采样的实时性和稳定度。你后面要加自己的业务代码,也应延续这个模式。
3. 核心模块的代码逻辑与配置细节
3.1 触摸检测模块:初始化与扫描流程
触摸模块是这颗芯片的核心竞争力,也是样例程序里最值得研究的部分。初始化通常分为三步:配置触摸通道对应的IO、设置充放电时间参数、选定扫描通道数。
void Touch_Init(void) { Touch_IO_Config(); // 设置触摸通道引脚 Touch_SetChargeTime(XX); // 设置充电时间 Touch_SetDischargeTime(XX); // 设置放电时间 Touch_EnableChannel(CH0|CH1|CH2); // 使能对应通道 Touch_StartScan(); // 启动首次扫描 }充放电时间参数直接影响触摸灵敏度。参数调得越大,对电容变化的响应越明显,但也更容易受外界干扰。实际项目里需要根据按键面板的介质厚度、焊盘大小来反复调。官方样例程序给的是典型值,在常规2mm亚克力面板、12mm圆形焊盘的情况下表现良好;如果你的面板更厚或者用了玻璃材质,就需要把这个参数适当调大。
触摸扫描完成之后,触摸库会在中断里更新键值,同时提供去抖处理。这里我要强调一点:不要在主循环里调用阻塞式的触摸读取函数,尽量以“扫描完成标志+缓存键值”的方式去读。
3.2 ADC模块:NTC测温与电位器检测的配置思路
CMS79FT738的ADC模块在样例里主要用来处理模拟信号源,最常见的两个用途就是NTC温度采样和电位器档位识别。初始化时你需要配置采样通道、转换位数和参考电压。
void ADC_Init(void) { ADC_Config(ADC_CH0, ADC_12BIT, ADC_VREF_VDD); ADC_Start(); } unsigned int ADC_ReadValue(void) { ADC_StartConvert(); while (!ADC_IsConversionComplete()); return ADC_GetResult(); }如果你之前用过其他8位机的ADC,过渡到这颗芯片基本没有压力。唯一要做的是滤波处理——直接拿单次采样值做NTC查表,结果会跳得比较厉害,建议在应用层做多次采样取平均,或者用一阶低通滤波。样例工程里已经放了平均值滤波的基础代码,直接调用即可。
3.3 PWM与定时器:蜂鸣器驱动和时间基准
PWM模块在样例里的作用主要是驱动蜂鸣器和LED调光。蜂鸣器这一块要留意:不同频率响应特性的蜂鸣器需要不同的PWM载波频率,常见的无源蜂鸣器工作在2.7kHz到4kHz之间。样例里默认给的是一组常用频率,你要是换了蜂鸣器型号,记得改这里的参数,否则会出现声音偏小或者刺耳的情况。
定时器模块则为基础时间节拍服务。常见配置是让定时器产生1ms中断,在中断服务函数里对软件计数器做累加,用于按键长按判断、数码管动态扫描、ADC周期采样等。这个设计很实用,能省掉多个硬件定时器。
volatile unsigned int g_tick_1ms = 0; void Timer_ISR(void) interrupt { g_tick_1ms++; if (g_tick_1ms % 500 == 0) { Touch_StartScan(); // 每500ms启动一次触摸扫描 } }这里多说一句,触摸扫描不需要一直开,很多低功耗产品是每隔一定时间才扫描一次。如果你做的是电池供电的设备,可以把扫描周期拉长、扫描完成就进入休眠模式,这样整机功耗可以压到很低。
3.4 主循环业务调度架构
主循环的写法决定了整个项目后期好不好维护。官方样例的写法简洁清晰:
void main(void) { System_Init(); Touch_Init(); ADC_Init(); Timer_Init(); while (1) { if (touch_flag) { handle_touch_key(); } if (adc_flag) { handle_temp_sample(); } handle_led_display(); } }我见过很多工程师喜欢在while循环里从头到尾把每个模块轮一遍,这种写法短期没问题,一旦外设多了,时序控制就会变得很乱。样例这种“事件标志+条件执行”的框架,在后续加功能、维护的时候会舒服得多。
4. 从零跑通工程:环境搭建与烧录调试
4.1 开发环境准备
中微的8位机开发环境支持Keil和自家IDE两种方式。我个人更推荐直接用Keil,熟悉度更高,编译速度也快。打开工程文件后,如果没有安装对应的芯片支持包,编译器会报错找不到器件,先装好中微的芯片包再打开工程就好。
工程打开后,第一件事不是点编译,而是到Options for Target里检查三样东西:芯片型号是否选对、Flash烧录算法是否匹配、优化等级是否合适。触摸库对编译器优化等级有一定要求,建议先保持官方样例的默认设置,跑通之后再根据实际情况调整优化等级。
4.2 烧录与在线调试
中微这系列芯片的烧录使用官方烧录器,通过SWD接口与板子相连。接好线后打开烧录工具,选择对应的芯片型号并加载编译生成的hex文件,点击烧录即可。
第一次烧录的时候我遇到过连接不上的情况,排查下来是目标板供电不足,SWD接口的复位脚被拉低导致进不了烧录模式。这个坑后面在问题排查部分会详细说。烧录成功后,使用IDE的Debug功能可以在线调试,设置断点查看变量。
5. 把样例程序移植到自己的板子上
5.1 引脚分配比对
移植的第一步是打开官方样例的原理图,再打开你自己的板子原理图,逐项核对引脚分配。不同的封装型号引脚数不同,触摸通道的映射可能会错位。建议在代码里把触摸通道和按键功能的对应关系整理成一张表:
| 按键功能 | 触摸通道 | IO引脚 | 备注 |
|---|---|---|---|
| 开关键 | CH0 | P16 | 直连焊盘 |
| 加键 | CH1 | P17 | 直连焊盘 |
| 减键 | CH2 | P27 | 直连焊盘 |
| 功能键 | CH3 | P30 | 直连焊盘 |
实际移植时,只改宏定义和初始化数组即可,不需要动触摸库内部逻辑。如果新板子的按键布局和官方样例差异很大,建议保留这个按键映射表,方便后续维护。
5.2 触摸灵敏度的调整方法
移植后最常遇到的情况就是触摸按键“不灵敏”或者“过于灵敏”,这时优先调整的不是元器件参数,而是触摸库里的灵敏度和阈值配置。可以分三步调:
- 不加任何干预,把触摸模块采到的基准值和按压后的值分别打印出来
- 对比两组数据的差值,差值就是“触摸增量”
- 将阈值设置在基准值加30%到50%触摸增量的位置,预留足够的余量
另外,焊盘的大小和形状对灵敏度影响很大。焊盘太小,触摸增量小,容易误触;焊盘太大,按键之间的互电容干扰又会加重。常规情况下,建议用12mm到16mm的圆形焊盘,按键间距至少5mm以上。
5.3 介质面板材料与厚度的影响
触摸按键上方覆盖的面板材质会直接影响充电时间和灵敏度。亚克力和玻璃的介电常数不同,触摸信号衰减也完全不同。换面板材料后,一定要重新测试,不能想当然沿用之前的参数。我的建议是每更换一次面板材料和厚度,就重新做一组灵敏度测试记录,标注好对应的充放电时间参数、阈值,方便后续追溯。
6. 调试中踩过的坑与可行的排查方案
6.1 烧录连接失败
这应该是大家遇到概率最高的第一次报错。烧录器能识别到芯片,但点击连接后一直提示失败。从我的经验来看,先检查目标板电源是否稳定,再用万用表确认接线是否正确。还有一个很容易忽略的点:部分烧录器要求目标板先上电,再连接烧录器,顺序反了也会导致连接失败。
如果还是不行,把SWD两根信号线上的上拉电阻检查一遍,注意可能被复位电路干扰。
6.2 触摸按键误触发或失灵
误触发多半是供电纹波导致的。触摸检测对电源稳定度比较敏感,触摸按键附近如果有继电器或者大功率负载,触点动作时的电压跌落会直接影响采样结果。解决办法是在电源输入端增加滤波电容,同时把触摸模块的扫描安排在负载动作完成的几十毫秒之后,避免与干扰同时发生。
失灵问题则大多数出在面板材料厚度或焊盘尺寸上,重新按前面说的方法调参即可。
6.3 温度漂移带来的基准值变化
环境温度变化后,触摸基准值会跟着漂移。如果初始化阶段只采样一次基准值并长期固定,温度变化后阈值相对新的基准值可能就不合适了。官方库一般支持“实时基准值更新”机制,也就是在无按键按下时缓慢跟踪基准值。开启这个功能后,按键的长期稳定性会好很多,但要让慢速更新速度明显慢于实际按下的变化速度,防止误纠偏。
6.4 低功耗模式下触摸扫描导致唤醒失败
这个坑容易出现在电池供电的产品里。触摸扫描为了降低功耗,把充放电时间调得很短、扫描频率也降到很低,结果手指按下去的时间太短,扫描还没完成就错过了。解决思路是让触摸模块具备“边扫描边判断”的能力,检测到有效信号后立即唤醒主控;或者采用两段式扫描,低频粗扫、命中后高频精扫,兼顾功耗和响应速度。
最后再分享一点个人经验
CMS79FT738/736这套芯片,从样例程序到实际量产项目之间,其实还隔着不少细节。比如灵敏度参数在不同批次PCB板材上的差异、触摸键与LED走线之间的耦合干扰、量产烧录时校准参数的统一管理等。这些经验很难在官方文档里一次性看到,需要自己在实际项目里一点点积累。建议你拿到这份官方原版样例程序之后,不要只停留在“能编译、能烧录、能跑”的阶段,而是顺着代码逻辑把每个模块的调用关系理一遍,最好再自己动手改一遍参数,触摸阈值调得过高或过低分别会产生什么现象。这样一轮走下来,你对这颗芯片的理解会扎实得多。后面遇到真正复杂的项目,也能更快定位到问题的根源。
本文还有配套的精品资源,点击获取