你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

MCU实战经验+关于mcu的IO操作问题.

[复制链接]
harvardx 提问时间:2014-4-1 17:05 /
 本文曾经在以前探讨过.现在再次来讨论一下.
 
以讲述avr单片机的io口操作。很多朋友都是由51单片机走向嵌入式系统,经历了51->430 51->pic 51->avr,这样一些转换,本人粗略学了51,后直接专攻avr,为此有一些心得,和一些雕虫小技的小伎俩,希望能抛砖引玉,引发同行反思,在工作中提供举一反三后的便利。
 
     想像51一样,在winavr中直接写上sbit KEY1 = p1^1,
 
然后用下列语句扫描键盘吗??
 
if(KEY1==0) keyval=1;
 
请看下面的宏定义,其中位段的手法来源于网络,本人纯属借鉴。之后的##,宏链接符,纯属自创,
 
各位先行使用以下宏后,有问题直接联系本人qq21332560讨论:注明验证信息:io口
 
//定义新的数据类型,方便进行IO端口操作。
typedef struct
 {
    unsigned char bit0:1 ;
    unsigned char bit1:1 ;
    unsigned char bit2:1 ;
    unsigned char bit3:1 ;
    unsigned char bit4:1 ;
    unsigned char bit5:1 ;
    unsigned char bit6:1 ;
    unsigned char bit7:1 ;
}bit_field;
 
#define GET_BIT(adr)   (*(( volatile bit_field * )(&adr)))
 
////////////////////////////////////////
#define AUTOINIT 1       //自动初始化IO方向寄存器无需在初始化程序中用PORTA=0X..;形式来初始化io控制寄存器,同时也不争的证明了avr单片机的端口输入/出切换功能
 
#if     AUTOINIT==1
 
    #define PORT(m,n)   GET_BIT(DDR##m).bit##n=1;\
                       GET_BIT(PORT##m).bit##n
#else
 
    #define PORT(m,n)  GET_BIT(PORT##m).bit##n
 
#endif 
////////////////////////////////////////
 
#if AUTOINIT==1
 
#define PIN(m,n) 
 
    (!(u08)(GET_BIT(DDR##m).bit##n=0) 
 
         &&\
     (u08)(GET_BIT(PORT##m).bit##n=1)
 
         &&\
              GET_BIT(PIN ##m).bit##n )
#else
 
    #define PIN(m,n)      GET_BIT(PIN##m).bit##n
 
#endif 
 //方便直观操作 自由设定单个io口的方向
#define DRA(n)            GET_BIT(DDRA).bit##n 
#define DRB(n)            GET_BIT(DDRB).bit##n
#define DRC(n)            GET_BIT(DDRC).bit##n
#define DRD(n)            GET_BIT(DDRD).bit##n
#define DDR(m,n)        GET_BIT(DDR##m).bit##n
 
在我们实际项目中,需要用到按键输入,继电器,SPI器件输出,
 
两者分别为输入,和输出之用,这时候可以方面的在各自c文件对应的.h文件中写下如下语句:
 
#define KEY1 PIN(C,3)//定义三个按键,使能上拉
#define KEY2 PIN(C,4)
#define KEY3 PIN(C,5)
 
#define SCLK_SPI  PORT(B,5)//定义spi口的两个控制引脚
#define CS_SPI      PORT(C,0)
 
上述PIN PORT 自动化定义的方法中,有些不足,如:在DS18B20这样的应用中,需要切换引脚的输入输出,就必须为18B20的引脚安排两套定义,
 
类似于:#define DS18B20_IN     PIN(A,1)
 
             #define DS18B20_OUT  PORT(A,1)
 
此外:PORT和PIN的自动化定义中,含有DDR的操作,凡是用到PIN和PORT定义过的端口的地方都需要重复DDR操作,带来冗余代码。
 
以上是对单片机端口的位操作的一点浅显认识;.在avr中有不错的便利应用.
 
可以看本人的一些实例代码;,
例程1:         定义3个按键输入口;
       #define KEY1 PIN(A,5)//
        #define KEY2 PIN(A,4)/
        #define KEY3 PIN(A,3)
        那么 : 按键读取就可以按照以下方式来进行:
u08 keyinput(void)
{
        u08 KeyVal=0;
        if(KEY_SET==0) KeyVal=        3;
        if(KEY_DEC==0) KeyVal=        2;
        if(KEY_ADD==0) KeyVal=        1;
         return KeyVal;
}
例程2:         定义:2个数据口,操作hc164,若干位选, 共同用于led数码管扫描显示;
#define HC164CLK                  PORT(B,4)//Hardware:4703v1.0
#define HC164DIO                  PORT(B,3) 
#define BIT1                          PORT(B,2) 
#define BIT2                          PORT(B,1)
#define BIT3                          PORT(B,0) 
#define BIT4                          PORT(A,0) 
#define BIT5                          PORT(A,1) 
#define BIT6                          PORT(A,2) 
/* 功能:发送一个字节8段码至hc164
*| 注意:HC164CLK为自定义位域字段,
*|
*/
void HC164_send_byte(unsigned char a)
{       
     unsigned char i;
 
     HC164_DIGRST();//传送数据时候的消隐处理 
 
    for( i = 0 ; i < 8 ; i++ )
    {       
            HC164CLK = 0;
 
            if( a & 0x80 )
         {
                HC164DIO = 1;
         }
            else
         {
                HC164DIO = 0;
         }

             a
收藏 评论11 发布时间:2014-4-1 17:05

举报

11个回答
witnessiz 回答时间:2014-4-16 13:22:42

RE:MCU实战经验+关于mcu的IO操作问题.

顶!
harvardx 回答时间:2014-4-16 13:25:02

RE:MCU实战经验+关于mcu的IO操作问题.

谢谢wit群  希望对同行兄弟们有用
qzwx741 回答时间:2014-4-16 13:27:13

RE:MCU实战经验+关于mcu的IO操作问题.

顶一下
clx1223 回答时间:2014-4-16 13:31:32

RE:MCU实战经验+关于mcu的IO操作问题.

赞一个,谢谢分享
mcu-354561 回答时间:2014-4-16 13:40:11

RE:MCU实战经验+关于mcu的IO操作问题.

LZ 厉害
用单个IO口操作 不论是8位机还是32位都感觉非常方便。
下面是stm8s 我常用的IO操作方式,其实地址修改一下,应该是可以
在其他8位IC里面的。
typedef struct GPIOX_struct
{
    union
    {
        volatile unsigned char DDR_;
        volatile unsigned char CR1_;
        volatile unsigned char CR2_;
        volatile unsigned char ODR_;
        volatile unsigned char IDR_;
        struct
        {
            volatile unsigned char R0:1;
            volatile unsigned char R1:1;
            volatile unsigned char R2:1;
            volatile unsigned char R3:1;
            volatile unsigned char R4:1;
            volatile unsigned char R5:1;
            volatile unsigned char R6:1;
            volatile unsigned char R7:1;
        }BIT_;
    };
}GPIOX_TypeDef;
#define GPIO_PAOUT    ((GPIOX_TypeDef *)0X5000)
#define PA            (GPIO_PAOUT->ODR_)
#define PA0           (GPIO_PAOUT->BIT_.R0)
#define PA1           (GPIO_PAOUT->BIT_.R1)
#define PA2           (GPIO_PAOUT->BIT_.R2)
#define PA3           (GPIO_PAOUT->BIT_.R3)
#define PA4           (GPIO_PAOUT->BIT_.R4)
#define PA5           (GPIO_PAOUT->BIT_.R5)
#define PA6           (GPIO_PAOUT->BIT_.R6)
#define PA7           (GPIO_PAOUT->BIT_.R7)
。。。。。。。
。。。。。。。
32位的 例如st 已经有大侠全部写好了 类似:
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)
harvardx 回答时间:2014-4-18 11:44:11

RE:MCU实战经验+关于mcu的IO操作问题.

楼上的又让我学习了 多谢
oipk 回答时间:2015-1-9 09:14:30
我记得S12的寄存器就是这么定义的,有感觉。
QianFan 回答时间:2015-1-9 12:20:52
有bitband的直接使用bitband就行,何必这么麻烦
dzzwoaizi 回答时间:2015-1-25 17:57:03
大哥,你太牛了,我会把你的帖子全部看完!
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版