当前位置:首页 >> 单片机入门 >> 新唐M051如何自制GPIO简化设置宏函数

新唐M051如何自制GPIO简化设置宏函数

新唐单片机 M0单片机 GPIO设置 作者: 来源: 发布时间:2018-12-27 14:07:09   浏览:9

近期因为工作项目开始真正的使用上新唐M051,开始领会到新唐M0尤其是M051的魅力所在,并深刻了解到官方的良苦用心。体会了M0+51的独特魅力,没错,他就是为了搅局8位机市场而来,目标就是成为和8051媲美的单片机.他做到了.avr时代很多人, 觉得端口单独赋值不方便:举例-
两个液晶端口: 
                      LCD_CLK  
                      LCD_DAT 
要拉高高低,很多人用标C,PORTA|=(1<<LCD_CLK_BIT);这种方式, 后来我利用位域+宏函数,实现了很51下比较兼容的操作习惯.只要定义: 
#define LCD_CLK    PORT(A,7)
#define LCD_DAT   PORT(A,6)

其中PORT(m,n) 为自己利用宏函数构造的宏,具体见笔者的《基于宏定义的超强avr单片机io口操作》。

这样,可以和51时代一样方便操作. LCD_CLK =1; 不同的是.51的端口定义方式是sbit LCD_CLK = Px.y; 在M0尤其是新唐M0可以实现这个目标吗:答案是YES

当然,使用这些GPIO,也就是普通io口钱,必须要把他们设定在GPIO模式,保证他们的其他功能,比如ad 串口,后者pwm 什么的 都没有开启.
这就要设置MFP寄存器:一般我们按照这样一个步骤来操作普通IO口,
void LED_Init(void)
{
        /* Configure P4.0 - P4.5 as GPIO mode */
        _SYS_P40_MFP(SYS_MFP_P40_GPIO);
        _SYS_P41_MFP(SYS_MFP_P41_GPIO);
        _SYS_P42_MFP(SYS_MFP_P42_GPIO);
        _SYS_P43_MFP(SYS_MFP_P43_GPIO);
        _SYS_P44_MFP(SYS_MFP_P44_GPIO);
        _SYS_P45_MFP(SYS_MFP_P45_GPIO);
        
        /* Configure P3.2 - P3.7 as GPIO mode */
        _SYS_P32_MFP(SYS_MFP_P32_GPIO);
        _SYS_P33_MFP(SYS_MFP_P33_GPIO);
        _SYS_P34_MFP(SYS_MFP_P34_GPIO);
        _SYS_P35_MFP(SYS_MFP_P35_GPIO);
        _SYS_P36_MFP(SYS_MFP_P36_GPIO);
        _SYS_P37_MFP(SYS_MFP_P37_GPIO);
        
        /* Configure P4.0 - P4.5 as Output mode */
    _GPIO_SET_PIN_MODE(P4, 0, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P4, 1, GPIO_PMD_OUTPUT);
        _GPIO_SET_PIN_MODE(P4, 2, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P4, 3, GPIO_PMD_OUTPUT);
        _GPIO_SET_PIN_MODE(P4, 4, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P4, 5, GPIO_PMD_OUTPUT);


        /* Configure P3.2 - P3.7 as Output mode */
        _GPIO_SET_PIN_MODE(P3, 2, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P3, 3, GPIO_PMD_OUTPUT);
        _GPIO_SET_PIN_MODE(P3, 4, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P3, 5, GPIO_PMD_OUTPUT);
        _GPIO_SET_PIN_MODE(P3, 6, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P3, 7, GPIO_PMD_OUTPUT);
        
        /* Configure P4.0 - P4.5 as HIGH */
        P40=P41=P42=P43=P44=P45=1;
        /* Configure P3.2 - P3.7 as HIGH */
        P32=P33=P34=P35=P36=P37=1;
}
1,首先,设置MFP为GPIO
2,其次,设定GPIO的PIN模式,是作为输出还是输入,还是双向,还是开漏;
3,最好就是可以对端口进行操作了.类似于51;
上面的三部曲,尤其是前2部曲,必须要要工具自己系统的原理图中的IO定义,不断地修改Pmn中的m和n ,比如这2个:
        _SYS_P40_MFP(SYS_MFP_P40_GPIO);
        _SYS_P41_MFP(SYS_MFP_P41_GPIO);
上面一句写完,下面的一句直接拷贝上面的,然后把语句中,所有的40改成41,除了这个MFP设置要改,后面的   
    _GPIO_SET_PIN_MODE(P4, 0, GPIO_PMD_OUTPUT);
    _GPIO_SET_PIN_MODE(P4, 1, GPIO_PMD_OUTPUT);


也要做响应改动. 如果IO多了 难免麻烦,枯燥,其实完全可以利用C的强大的宏来代替我们完成这些,如果如下这样,感觉就轻松多了.
        /* 1--Configure P0.1\P0.2\P0.3\P0.4\P0.5\ as GPIO mode 
    *  meanwhile, set the PIN mode:
    */
    SET_MFP_GPIO(0,1,GPIO_PMD_QUASI);
    SET_MFP_GPIO(0,2,GPIO_PMD_QUASI );
    SET_MFP_GPIO(0,3,GPIO_PMD_QUASI);
    SET_MFP_GPIO(0,4,GPIO_PMD_INPUT);
    SET_MFP_GPIO(0,5,GPIO_PMD_INPUT);
,第一句写好,第二句,就是改1-2个数字的事情.非常方便,当然PIN的模式要改的时候,可以把后面的GPIO_PMD_QUASI,模式定义修改成其他的.这样操作几种很多了.SET_MFP_GPIO(m,n,mode) 这个函数帮了大忙. 这个函数本身还是借助于官方的Bsp ,只不过做了归纳总结.具体的技术细节如下:




/** 设置Pm.n的MFP为GPIO,且选择IO模式 
*   1,Setting port_m的 pin_n引脚为GPIO
*   2,setting port_m的 pin_n引脚的输入输出模式pin mode
*/
#define SET_MFP_GPIO(port_m,pin_n,PINmode)                 _SYS_P##port_m##pin_n##_MFP(SYS_MFP_P##port_m##pin_n##_GPIO); \
                                                                                           _GPIO_SET_PIN_MODE(P##port_m, pin_n, PINmode)


主要是利用了宏链接符,##, 把原来的分散性的分布操作.集中起来.统一管理操作. 各位同学,觉得有用.可以 收藏一下.不增加代码,但是提高了便利性.

编辑:admin  最后修改时间:2018-12-27