打印
[电路设计]

C++/C 玩单片机IO口

[复制链接]
2064|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CC2530|  楼主 | 2011-5-24 18:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 CC2530 于 2011-5-25 20:29 编辑

IAR AVR编译
C++:
#include <intrinsics.h>
#include <stddef.h>
#include <ioavr.h>


#ifndef _BV
#define _BV(A) (1U<<(A))
#endif

#ifndef __always_inline__
#define __always_inline__ _Pragma("inline=forced") inline
#endif

typedef unsigned char uint8;

#define __AVR_GPIO_ASSIGN(A, B, C) \
__always_inline__ static void Set(void) {PORT##B |= _BV(C);}\
__always_inline__ static void Clr(void) {PORT##B &= ~_BV(C);}\
__always_inline__ static void MakeOut(void) {DDR##B |= _BV(C);}\
__always_inline__ static void MakeIn(void) {DDR##B &= ~_BV(C);}\
__always_inline__ static void MakeOutHigh(void) {Set(); MakeOut();}\
__always_inline__ static void MakeOutLow(void) {Clr(); MakeOut();}\
__always_inline__ static void MakeInHighImpedance(void) {DDR##B &= ~_BV(C); PORT##B &= ~_BV(C);}\
__always_inline__ static void MakeInPullUp(void) {DDR##B &= ~_BV(C); PORT##B |= _BV(C);}\
__always_inline__ static void Toggle(void) {PORT##B ^= _BV(C);}\
__always_inline__ static uint8 ReadIn(void) {return ((PIN##B & _BV(C)) != 0);}\
__always_inline__ static uint8 ReadOut(void) {return ((PORT##B & _BV(C)) != 0);}\
__always_inline__ static uint8 ReadDir(void) {return ((DDR##B & _BV(C)) != 0);}\
__always_inline__ static uint8 Read(void) {return ReadIn();}\
__always_inline__ static void Out(uint8 x) {(x)?(Set())Clr());}\
__always_inline__ static uint8 IsOutHigh(void) {return ReadOut();}\
__always_inline__ static uint8 IsOutLow(void) {return !ReadOut();}\

#define __AVR_GPIO_ASSIGN_POLARITY(A, B, C,X) \
__AVR_GPIO_ASSIGN(A, B, C)\
__always_inline__ static void On(void) { (X)?(Set())Clr());}\
__always_inline__ static void Off(void) {(!X)?(Set())Clr());}\
__always_inline__ static void MakeOutOn(void) {On();MakeOut();}\
__always_inline__ static void MakeOutOff(void) {Off();MakeOut();}\
__always_inline__ static uint8 IsOn(void) {return (X)?IsOutHigh():IsOutLow();}\
__always_inline__ static uint8 IsOff(void) {return (!X)?IsOutHigh():IsOutLow();}



#define AVR_GPIO_ASSIGN(A, B, C) \
static class class##A{\
public:\
__AVR_GPIO_ASSIGN(A, B, C)\
} A;

#define AVR_GPIO_ASSIGN_POLARITY(A, B, C,X) \
static class class##A{\
public:\
__AVR_GPIO_ASSIGN_POLARITY(A, B, C,X)\
} A;


AVR_GPIO_ASSIGN_POLARITY(LED_0,D,0,1); //LED_0D0:高电平亮
AVR_GPIO_ASSIGN_POLARITY(LED_1,D,1,0); //LED_1D1:低电平亮
AVR_GPIO_ASSIGN(LED_2,D,2); //LED_2D2


volatile uint8 read;

void test(void)
{
LED_0.MakeOut(); //LED_0设置为输出
LED_0.Set(); //LED_0输出高
LED_0.Clr(); //LED_0输出低
LED_0.Toggle(); //LED_0翻转
LED_0.On(); //LED_0亮
LED_0.Off(); //LED_0灭

(&LED_0)->MakeOut(); //LED_0设置为输出
(&LED_0)->Set(); //LED_0输出高
(&LED_0)->Clr(); //LED_0输出低
(&LED_0)->Toggle(); //LED_0翻转
(&LED_0)->On(); //LED_0亮
(&LED_0)->Off(); //LED_0灭


LED_1.MakeOut(); //LED_1设置为输出
LED_1.Set(); //LED_1输出高
LED_1.Clr(); //LED_1输出低
LED_1.Toggle(); //LED_1翻转
LED_1.On(); //LED_1亮
LED_1.Off(); //LED_1灭

(&LED_1)->MakeOut(); //LED_1设置为输出
(&LED_1)->Set(); //LED_1输出高
(&LED_1)->Clr(); //LED_1输出低
(&LED_1)->Toggle(); //LED_1翻转
(&LED_1)->On(); //LED_1亮
(&LED_1)->Off(); //LED_1灭

LED_2.MakeInHighImpedance(); //LED_2设置为高阻输入
LED_2.MakeInPullUp(); //LED_2设置为上拉输入
LED_2.MakeOutHigh(); //LED_2设置为输出高
LED_2.MakeOutLow(); //LED_2设置为上拉输入

read=LED_2.ReadIn(); //读取LED_2引脚点品
read=LED_2.ReadDir(); //读取LED_2方向
read=LED_2.ReadOut(); //如果LED_2端口寄存器

(&LED_2)->MakeInHighImpedance(); //LED_2设置为高阻输入
(&LED_2)->MakeInPullUp(); //LED_2设置为上拉输入
(&LED_2)->MakeOutHigh(); //LED_2设置为输出高
(&LED_2)->MakeOutLow(); //LED_2设置为上拉输入

read=(&LED_2)->ReadIn(); //读取LED_2引脚点品
read=(&LED_2)->ReadDir(); //读取LED_2方向
read=(&LED_2)->ReadOut(); //如果LED_2端口寄存器

}
汇编:
 RSEG CODE:CODE:NOROOT(1)
// 65 void test(void)
??test:
// 66 {
// 67 LED_0.MakeOut(); //LED_0设置为输出
SBI 0x11, 0x00
// 68 LED_0.Set(); //LED_0输出高
SBI 0x12, 0x00
// 69 LED_0.Clr(); //LED_0输出低
CBI 0x12, 0x00
// 70 LED_0.Toggle(); //LED_0翻转
LDI R16, 1
IN R17, 0x12
EOR R17, R16
OUT 0x12, R17
// 71 LED_0.On(); //LED_0亮
SBI 0x12, 0x00
// 72 LED_0.Off(); //LED_0灭
CBI 0x12, 0x00
// 73
// 74 (&LED_0)->MakeOut(); //LED_0设置为输出
SBI 0x11, 0x00
// 75 (&LED_0)->Set(); //LED_0输出高
SBI 0x12, 0x00
// 76 (&LED_0)->Clr(); //LED_0输出低
CBI 0x12, 0x00
// 77 (&LED_0)->Toggle(); //LED_0翻转
IN R17, 0x12
EOR R17, R16
OUT 0x12, R17
// 78 (&LED_0)->On(); //LED_0亮
SBI 0x12, 0x00
// 79 (&LED_0)->Off(); //LED_0灭
CBI 0x12, 0x00
// 80
// 81
// 82 LED_1.MakeOut(); //LED_1设置为输出
SBI 0x11, 0x01
// 83 LED_1.Set(); //LED_1输出高
SBI 0x12, 0x01
// 84 LED_1.Clr(); //LED_1输出低
CBI 0x12, 0x01
// 85 LED_1.Toggle(); //LED_1翻转
LDI R16, 2
IN R17, 0x12
EOR R17, R16
OUT 0x12, R17
// 86 LED_1.On(); //LED_1亮
CBI 0x12, 0x01
// 87 LED_1.Off(); //LED_1灭
SBI 0x12, 0x01
// 88
// 89 (&LED_1)->MakeOut(); //LED_1设置为输出
SBI 0x11, 0x01
// 90 (&LED_1)->Set(); //LED_1输出高
SBI 0x12, 0x01
// 91 (&LED_1)->Clr(); //LED_1输出低
CBI 0x12, 0x01
// 92 (&LED_1)->Toggle(); //LED_1翻转
IN R17, 0x12
EOR R17, R16
OUT 0x12, R17
// 93 (&LED_1)->On(); //LED_1亮
CBI 0x12, 0x01
// 94 (&LED_1)->Off(); //LED_1灭
SBI 0x12, 0x01
// 95
// 96 LED_2.MakeInHighImpedance(); //LED_2设置为高阻输入
CBI 0x11, 0x02
CBI 0x12, 0x02
// 97 LED_2.MakeInPullUp(); //LED_2设置为上拉输入
CBI 0x11, 0x02
SBI 0x12, 0x02
// 98 LED_2.MakeOutHigh(); //LED_2设置为输出高
SBI 0x12, 0x02
SBI 0x11, 0x02
// 99 LED_2.MakeOutLow(); //LED_2设置为上拉输入
CBI 0x12, 0x02
SBI 0x11, 0x02
// 100
// 101 read=LED_2.ReadIn(); //读取LED_2引脚点品
SBIS 0x10, 0x02
RJMP ??test_1
LDI R16, 1
RJMP ??test_2
??test_1:
LDI R16, 0
??test_2:
STS `read`, R16
// 102 read=LED_2.ReadDir(); //读取LED_2方向
SBIS 0x11, 0x02
RJMP ??test_3
LDI R16, 1
RJMP ??test_4
??test_3:
LDI R16, 0
??test_4:
STS `read`, R16
// 103 read=LED_2.ReadOut(); //如果LED_2端口寄存器
SBIS 0x12, 0x02
RJMP ??test_5
LDI R16, 1
RJMP ??test_6
??test_5:
LDI R16, 0
??test_6:
STS `read`, R16
// 104
// 105 (&LED_2)->MakeInHighImpedance(); //LED_2设置为高阻输入
CBI 0x11, 0x02
CBI 0x12, 0x02
// 106 (&LED_2)->MakeInPullUp(); //LED_2设置为上拉输入
CBI 0x11, 0x02
SBI 0x12, 0x02
// 107 (&LED_2)->MakeOutHigh(); //LED_2设置为输出高
SBI 0x12, 0x02
SBI 0x11, 0x02
// 108 (&LED_2)->MakeOutLow(); //LED_2设置为上拉输入
CBI 0x12, 0x02
SBI 0x11, 0x02
// 109
// 110 read=(&LED_2)->ReadIn(); //读取LED_2引脚点品
SBIS 0x10, 0x02
RJMP ??test_7
LDI R16, 1
RJMP ??test_8
??test_7:
LDI R16, 0
??test_8:
STS `read`, R16
// 111 read=(&LED_2)->ReadDir(); //读取LED_2方向
SBIS 0x11, 0x02
RJMP ??test_9
LDI R16, 1
RJMP ??test_10
??test_9:
LDI R16, 0
??test_10:
STS `read`, R16
// 112 read=(&LED_2)->ReadOut(); //如果LED_2端口寄存器
SBIS 0x12, 0x02
RJMP ??test_11
LDI R16, 1
RJMP ??test_12
??test_11:
LDI R16, 0
??test_12:
STS `read`, R16
// 113
// 114 }
RET

相关帖子

沙发
CC2530|  楼主 | 2011-5-24 18:45 | 只看该作者
C:

#include <intrinsics.h>
#include <stddef.h>
#include <ioavr.h>


#ifndef _BV
#define _BV(A)  (1U<<(A))
#endif

#ifndef __always_inline__
#define __always_inline__  _Pragma("inline=forced") inline
#endif

typedef unsigned char uint8;


#define AVR_GPIO_ASSIGN(A, B, C) \
__always_inline__ static void   GPIO_##A##_Set(void)            {PORT##B |=  _BV(C);}\
__always_inline__ static void   GPIO_##A##_Clr(void)            {PORT##B &= ~_BV(C);}\
__always_inline__ static void   GPIO_##A##_MakeOut(void)        {DDR##B  |=  _BV(C);}\
__always_inline__ static void   GPIO_##A##_MakeIn(void)         {DDR##B  &= ~_BV(C);}\
__always_inline__ static void   GPIO_##A##_MakeOutHigh(void)    {GPIO_##A##_Set(); GPIO_##A##_MakeOut();}\
__always_inline__ static void   GPIO_##A##_MakeOutLow(void)     {GPIO_##A##_Clr(); GPIO_##A##_MakeOut();}\
__always_inline__ static void   GPIO_##A##_MakeInHighImpedance(void)  {DDR##B &= ~_BV(C); PORT##B &= ~_BV(C);}\
__always_inline__ static void   GPIO_##A##_MakeInPullUp(void)   {DDR##B &= ~_BV(C); PORT##B |=  _BV(C);}\
__always_inline__ static void   GPIO_##A##_Toggle(void)         {PORT##B ^= _BV(C);}\
__always_inline__ static uint8  GPIO_##A##_ReadIn(void)         {return ((PIN##B & _BV(C)) != 0);}\
__always_inline__ static uint8  GPIO_##A##_ReadOut(void)        {return ((PORT##B & _BV(C)) != 0);}\
__always_inline__ static uint8  GPIO_##A##_ReadDir(void)        {return ((DDR##B & _BV(C)) != 0);}\
__always_inline__ static uint8  GPIO_##A##_Read(void)           {return GPIO_##A##_ReadIn();}\
__always_inline__ static void   GPIO_##A##_Out(uint8 x)         {(x)?(GPIO_##A##_Set()):(GPIO_##A##_Clr());}\
__always_inline__ static uint8  GPIO_##A##_IsOutHigh(void)      {return GPIO_##A##_ReadOut();}\
__always_inline__ static uint8  GPIO_##A##_IsOutLow(void)       {return !GPIO_##A##_ReadOut();}

#define AVR_GPIO_ASSIGN_POLARITY(A, B, C,X) \
AVR_GPIO_ASSIGN(A, B, C)\
__always_inline__ static void   GPIO_##A##_On(void)             { (X)?(GPIO_##A##_Set()):(GPIO_##A##_Clr());}\
__always_inline__ static void   GPIO_##A##_Off(void)            {(!X)?(GPIO_##A##_Set()):(GPIO_##A##_Clr());}\
__always_inline__ static void   GPIO_##A##_MakeOutOn(void)      {GPIO_##A##_On();GPIO_##A##_MakeOut();}\
__always_inline__ static void   GPIO_##A##_MakeOutOff(void)     {GPIO_##A##_Off();GPIO_##A##_MakeOut();}\
__always_inline__ static uint8  GPIO_##A##_IsOn(void)           {return  (X)?GPIO_##A##_IsOutHigh():GPIO_##A##_IsOutLow();}\
__always_inline__ static uint8  GPIO_##A##_IsOff(void)          {return (!X)?GPIO_##A##_IsOutHigh():GPIO_##A##_IsOutLow();}

//编译时有警告,放在头文件里面,就不会有警告
AVR_GPIO_ASSIGN_POLARITY(LED_0,D,0,1);  //LED_0:PD0:高电平亮
AVR_GPIO_ASSIGN_POLARITY(LED_1,D,1,0);  //LED_1:PD1:低电平亮
AVR_GPIO_ASSIGN(LED_2,D,2);             //LED_2:PD2


volatile uint8 read;

void test(void)
{
  GPIO_LED_0_MakeOut();         //LED_0设置为输出
  GPIO_LED_0_Set();             //LED_0输出高
  GPIO_LED_0_Clr();             //LED_0输出低
  GPIO_LED_0_Toggle();          //LED_0翻转
  GPIO_LED_0_On();              //LED_0亮
  GPIO_LED_0_Off();             //LED_0灭
   
   
  GPIO_LED_1_MakeOut();         //LED_1设置为输出
  GPIO_LED_1_Set();             //LED_1输出高
  GPIO_LED_1_Clr();             //LED_1输出低
  GPIO_LED_1_Toggle();          //LED_1翻转
  GPIO_LED_1_On();              //LED_1亮
  GPIO_LED_1_Off();             //LED_1灭
   
  
  GPIO_LED_2_MakeInHighImpedance();  //LED_2设置为高阻输入
  GPIO_LED_2_MakeInPullUp();         //LED_2设置为上拉输入
  GPIO_LED_2_MakeOutHigh();          //LED_2设置为输出高
  GPIO_LED_2_MakeOutLow();           //LED_2设置为上拉输入
  
  read=GPIO_LED_2_ReadIn();          //读取LED_2引脚点品  
  read=GPIO_LED_2_ReadDir();         //读取LED_2方向
  read=GPIO_LED_2_ReadOut();         //如果LED_2端口寄存器
  
}

汇编:
[code]
        RSEG CODE:CODE:NOROOT(1)
//   52 void test(void)
test:
//   53 {
//   54   GPIO_LED_0_MakeOut();         //LED_0设置为输出
        SBI     0x11, 0x00
//   55   GPIO_LED_0_Set();             //LED_0输出高
        SBI     0x12, 0x00
//   56   GPIO_LED_0_Clr();             //LED_0输出低
        CBI     0x12, 0x00
//   57   GPIO_LED_0_Toggle();          //LED_0翻转
        LDI     R16, 1
        IN      R17, 0x12
        EOR     R17, R16
        OUT     0x12, R17
//   58   GPIO_LED_0_On();              //LED_0亮
        SBI     0x12, 0x00
//   59   GPIO_LED_0_Off();             //LED_0灭
        CBI     0x12, 0x00
//   60   
//   61   
//   62   GPIO_LED_1_MakeOut();         //LED_1设置为输出
        SBI     0x11, 0x01
//   63   GPIO_LED_1_Set();             //LED_1输出高
        SBI     0x12, 0x01
//   64   GPIO_LED_1_Clr();             //LED_1输出低
        CBI     0x12, 0x01
//   65   GPIO_LED_1_Toggle();          //LED_1翻转
        LDI     R16, 2
        IN      R17, 0x12
        EOR     R17, R16
        OUT     0x12, R17
//   66   GPIO_LED_1_On();              //LED_1亮
        CBI     0x12, 0x01
//   67   GPIO_LED_1_Off();             //LED_1灭
        SBI     0x12, 0x01
//   68   
//   69   
//   70   GPIO_LED_2_MakeInHighImpedance();  //LED_2设置为高阻输入
        CBI     0x11, 0x02
        CBI     0x12, 0x02
//   71   GPIO_LED_2_MakeInPullUp();         //LED_2设置为上拉输入
        CBI     0x11, 0x02
        SBI     0x12, 0x02
//   72   GPIO_LED_2_MakeOutHigh();          //LED_2设置为输出高
        SBI     0x12, 0x02
        SBI     0x11, 0x02
//   73   GPIO_LED_2_MakeOutLow();           //LED_2设置为上拉输入
        CBI     0x12, 0x02
        SBI     0x11, 0x02
//   74   
//   75   read=GPIO_LED_2_ReadIn();          //读取LED_2引脚点品  
        SBIS    0x10, 0x02
        RJMP    ??test_0
        LDI     R16, 1
        RJMP    ??test_1
??test_0:
        LDI     R16, 0
??test_1:
        STS     `read`, R16
//   76   read=GPIO_LED_2_ReadDir();         //读取LED_2方向
        SBIS    0x11, 0x02
        RJMP    ??test_2
        LDI     R16, 1
        RJMP    ??test_3
??test_2:
        LDI     R16, 0
??test_3:
        STS     `read`, R16
//   77   read=GPIO_LED_2_ReadOut();         //如果LED_2端口寄存器
        SBIS    0x12, 0x02
        RJMP    ??test_4
        LDI     R16, 1
        RJMP    ??test_5
??test_4:
        LDI     R16, 0
??test_5:
        STS     `read`, R16
//   78   
//   79 }
        RET
[/code]

使用特权

评论回复
板凳
CC2530|  楼主 | 2011-5-24 18:49 | 只看该作者
IAR工程

iar_avr.rar

18.31 KB

iar_avr_cpp.rar

24.19 KB

使用特权

评论回复
地板
murex| | 2011-5-24 21:57 | 只看该作者
IAR还不会用,哈

使用特权

评论回复
5
hotpower| | 2011-5-25 01:15 | 只看该作者
欢迎加入 LOOK阵营

使用特权

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

本版积分规则

个人签名:该死的ST,还不赶快出STM8L小FLASH片子

0

主题

262

帖子

1

粉丝