本帖最后由 Harvard 于 2017-4-28 16:48 编辑
根据客户需求,设计一款具有彩屏界面的理疗仪. 主要有热敷,振动,激光. 快速设定按钮和单项调节按键共计10多个按钮. 带双色工作指示灯. 具备总线输出治疗方式 ,接智能探头; 亦有常规控制探头,由单片机
控制电机的启停, 恒温控制,激光功率调节等;
2, 选用新唐M0的原因: 个人对新唐单片机,尤其是M0单片机有着深刻的应用经验,在抛弃avr后, 新唐M0这一继任者.完全有过之而无不及. 非站台背书,是个人使用的感觉和产品实际运行结果确实如此. avr市面充斥翻新货,新货megaxxA系列也因为新的降成本的制程而没有当年的avr的风采. 而新唐M0 .2.5-5.5v的设计确实非常讨喜. 兼容51的操作方式.让我们这些只会玩玩8051 或者8位机的人,上手很快. 最简单的例子.要操作一个IO.
8051: sbit CLK = P1^1; CLK =1;
avr: PORTA |=(1<<0);
M0 : #define CLK P11 CLK =1;
可以看出,新唐软件库里面也做了大量的工作,比友商的cortexM操作某个io方便多了 , 让习惯了 8051或者8位机的工程师,可以方便的切换到M0 .
软件问题解决,其实硬件设计也是非常简单, 新唐配备了Nucad和Nutool-pinconfig,还有pinview
1, pinconfig 可以让你非常简单的去分配复用的io ,然我们随时了解,那些io这样用没有问题. 串口是映射在哪个io , 等等.
2. 配置完了以后,会自动产生出引脚的配置代码.
3, 还不止, 可以通过自动调用nucad ,自动生成sch或者orcad的原理图...
4,这些配置到底对不对呢? 不放心的画 ,可以用个对应mcu的sdk板,比如大新塘送了很多年的M051开发板.直接把刚才的配置代码编译后 ,利用mdk 在线调试 然后在debug菜单下,就可以利用打开pinview
图中,可以轻松看到串口的波特率 ,模拟量输入在那个脚. 非常直观.全球仅此一家.哈哈 夸张了. 确实简单实用.
原理图如下. 3路pwm.一路控温, 一路输出给激光器 ,调节强度; 一路pwm调节电机的速度;
3,主程序
/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
/** 1-BSP系统初始化 */
SYS_Init();
GPIO_Init();
P20 =0;
P21=0;
P22=1;
/* 2- 蜂鸣器和led测试 */
BUZZER =1;_delay_ms(10);
BUZZER =0;_delay_ms(10);
BUZZER =1;_delay_ms(10);
BUZZER =0;
/** 2-应用程序系统初始化*/
/* 关全局中断 便于初始化单片机 */
cli();
/* 定时器初始化 */
TMR0_Init();
TMR1_Init();
TMR2_Init();
TMR3_Init();
/* 开全局中断 结束初始化 */
sei();
/* pwm初始化 */
pwm_init();
/* adc初始化 */
ADC_initial();
/* dgus波特率设置 */
usart1_init(4800);
/** 带通信功能则初始化串口*/
usart_init( 4800 );
usart_en_recv( );
/* 测试代码 */
BUZZER =0;
LED_WAIT = LED_OFF; LED_WORK =LED_OFF;
/* 应用程序初始化 : */
/* 1- 上电后,显示**画面 */
menu_show(SYS_menu_index);
/* 2-关闭所有的pwm输出 */
pwm_update(0,0);
pwm_update(1,0);
pwm_update(2,0);
/* 开始系统倒计时 */
set_on_timer(TMR0,0,60,timer0_timeout);
/* 主循环 */
while(1)
{
/*0 - 按键扫描,处理 */
keyscan();
KeyProcess();
/*1- 看门狗 */
wdt_reset();
/*2- dgus处理 */
//dgus_process();
/*3- dgus界面刷新 */
dgus_show_update();
/*4 - 周期性的控制程序 */
if(f200ms)
{
f200ms = false;
}
/* 5- 温度控制程序 */
temperatue_proc();
/* 6- 软件定时器响应 */
on_timer();
/* 7- pwm更新处理 */
pwm_update_loop();
}
}
4 pwm 初始化程序
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 初始化pwm,设定两路方波所在的pwm的最小脉宽
*
* @param[in]
*
* [url=home.php?mod=space&uid=266161]@return[/url]
*
* [url=home.php?mod=space&uid=1543424]@Details[/url] 利用BSP库的功能,初始化M051内部的PWM模块
* 当前2个pwm引脚为: P24 ,P25,P26,P27
*/
void pwm_init( void )
{
/* 1- 设定P2.5引脚用于PWM5 输出.
* 设定引脚P42用于PWM2
*/
SYS_UnlockReg();
/* Enable PWM module clock */
CLK_EnableModuleClock(PWM01_MODULE);
CLK_EnableModuleClock(PWM23_MODULE);
/* Select PWM module clock source:改为外部晶振,可以得到准确的频率 :22MHZ */
CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HIRC, 0);
CLK_SetModuleClock(PWM23_MODULE, CLK_CLKSEL1_PWM23_S_HIRC, 0);
/* Reset PWMA channel4~channel7 */
SYS_ResetModule(PWM03_RST);
/* 设定各个pwm所在端口 */
SYS->P2_MFP &= ~(SYS_MFP_P20_Msk|SYS_MFP_P21_Msk|SYS_MFP_P22_Msk|SYS_MFP_P23_Msk);
SYS->P2_MFP |= SYS_MFP_P20_PWM0|SYS_MFP_P21_PWM1 |SYS_MFP_P22_PWM2 ;
GPIO_SetMode(P2, (1<<0)|(1<<1)|(1<<2)|(1<<3), GPIO_PMD_OUTPUT);
/* 2- 设定 PWM5的频率和占空比.
* 设定 PWM2的频率和占空比
*/
/* 2-1 输出通道1 - PWM4-7 (PWMB 0-3)
* 输出通道0-3:PWM0-3 (PWMA,0-3)
*/
/* Enable PWM Output pin :PWM2-PWMA, bit1*/
//PWM_EnableOutput(PWMB, (1<<0)|(1<<1)|(1<<2)|(1<<3) );
PWM_EnableOutput(PWMA, (1<<0)|(1<<1)|(1<<2));
/* 配置预分频为12: 频率为1mhz*/
PWM_SET_PRESCALER(PWMA,0,1);//2预分频率, 11MHZ
PWM_SET_PRESCALER(PWMA,1,1);//2预分频率
PWM_SET_PRESCALER(PWMA,2,1);//2预分频率
/* 配置时钟为1分频 :如此每个pwm的tick为0.1us*/
PWM_SET_DIVIDER(PWMA,0,PWM_CLK_DIV_1);
PWM_SET_DIVIDER(PWMA,1,PWM_CLK_DIV_1);
PWM_SET_DIVIDER(PWMA,2,PWM_CLK_DIV_1);
PWM_SET_DIVIDER(PWMA,3,PWM_CLK_DIV_1);
/* 设置频率为单次触发模式 */
_PWM_SET_TIMER_AUTO_RELOAD_MODE(PWMA,0);
_PWM_SET_TIMER_AUTO_RELOAD_MODE(PWMA,1);
_PWM_SET_TIMER_AUTO_RELOAD_MODE(PWMA,2);
/* 设置CNR,设置CMR: 脉宽0-0.1ms; 周期 0.1ms 10khz */
PWM_SET_CMR(PWMA,0,0); PWM_SET_CNR(PWMA,0,1000);
PWM_SET_CMR(PWMA,1,0); PWM_SET_CNR(PWMA,1,1000);
PWM_SET_CMR(PWMA,2,0); PWM_SET_CNR(PWMA,2,1000);
/*P22:设置为反相输出 */
PWM_ENABLE_OUTPUT_INVERTER(PWMA,1<<2);
/* 使能各个中断 */
// PWM_EnablePeriodInt(PWMB,0,PWM_PERIOD_INT_UNDERFLOW);
// PWM_EnablePeriodInt(PWMB,1,PWM_PERIOD_INT_UNDERFLOW);
// PWM_EnablePeriodInt(PWMB,2,PWM_PERIOD_INT_UNDERFLOW);
//PWM_EnablePeriodInt(PWMB,3,PWM_PERIOD_INT_UNDERFLOW);
/* Enable PWMB NVIC */
// NVIC_EnableIRQ((IRQn_Type)(PWMB_IRQn)); /* 使能中断 */
/* Enable PWM Timer */
PWM_Start(PWMA, (1<<0)|(1<<1)|(1<<2)|(1<<3) );
SYS_LockReg();
}
5 总结
新唐讲真,还是不凑. EMC ESD啥的 感觉不用操心太多.也没啥坏. 很耐++. 安利一下. 当然各大友商的M0-M7 除了评测 也没怎么批量用过.没有发言权. 新唐芯给力芯,加油吧.
早点出M23 M33 或者M7出来玩玩霸.
|
|