[电路设计] C++/C 玩单片机IO口

[复制链接]
2459|4
 楼主| CC2530 发表于 2011-5-24 18:43 | 显示全部楼层 |阅读模式
本帖最后由 CC2530 于 2011-5-25 20:29 编辑

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


  4. #ifndef _BV
  5. #define _BV(A) (1U<<(A))
  6. #endif

  7. #ifndef __always_inline__
  8. #define __always_inline__ _Pragma("inline=forced") inline
  9. #endif

  10. typedef unsigned char uint8;

  11. #define __AVR_GPIO_ASSIGN(A, B, C) \
  12. __always_inline__ static void Set(void) {PORT##B |= _BV(C);}\
  13. __always_inline__ static void Clr(void) {PORT##B &= ~_BV(C);}\
  14. __always_inline__ static void MakeOut(void) {DDR##B |= _BV(C);}\
  15. __always_inline__ static void MakeIn(void) {DDR##B &= ~_BV(C);}\
  16. __always_inline__ static void MakeOutHigh(void) {Set(); MakeOut();}\
  17. __always_inline__ static void MakeOutLow(void) {Clr(); MakeOut();}\
  18. __always_inline__ static void MakeInHighImpedance(void) {DDR##B &= ~_BV(C); PORT##B &= ~_BV(C);}\
  19. __always_inline__ static void MakeInPullUp(void) {DDR##B &= ~_BV(C); PORT##B |= _BV(C);}\
  20. __always_inline__ static void Toggle(void) {PORT##B ^= _BV(C);}\
  21. __always_inline__ static uint8 ReadIn(void) {return ((PIN##B & _BV(C)) != 0);}\
  22. __always_inline__ static uint8 ReadOut(void) {return ((PORT##B & _BV(C)) != 0);}\
  23. __always_inline__ static uint8 ReadDir(void) {return ((DDR##B & _BV(C)) != 0);}\
  24. __always_inline__ static uint8 Read(void) {return ReadIn();}\
  25. __always_inline__ static void Out(uint8 x) {(x)?(Set())Clr());}\
  26. __always_inline__ static uint8 IsOutHigh(void) {return ReadOut();}\
  27. __always_inline__ static uint8 IsOutLow(void) {return !ReadOut();}\

  28. #define __AVR_GPIO_ASSIGN_POLARITY(A, B, C,X) \
  29. __AVR_GPIO_ASSIGN(A, B, C)\
  30. __always_inline__ static void On(void) { (X)?(Set())Clr());}\
  31. __always_inline__ static void Off(void) {(!X)?(Set())Clr());}\
  32. __always_inline__ static void MakeOutOn(void) {On();MakeOut();}\
  33. __always_inline__ static void MakeOutOff(void) {Off();MakeOut();}\
  34. __always_inline__ static uint8 IsOn(void) {return (X)?IsOutHigh():IsOutLow();}\
  35. __always_inline__ static uint8 IsOff(void) {return (!X)?IsOutHigh():IsOutLow();}



  36. #define AVR_GPIO_ASSIGN(A, B, C) \
  37. static class class##A{\
  38. public:\
  39. __AVR_GPIO_ASSIGN(A, B, C)\
  40. } A;

  41. #define AVR_GPIO_ASSIGN_POLARITY(A, B, C,X) \
  42. static class class##A{\
  43. public:\
  44. __AVR_GPIO_ASSIGN_POLARITY(A, B, C,X)\
  45. } A;


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


  49. volatile uint8 read;

  50. void test(void)
  51. {
  52. LED_0.MakeOut(); //LED_0设置为输出
  53. LED_0.Set(); //LED_0输出高
  54. LED_0.Clr(); //LED_0输出低
  55. LED_0.Toggle(); //LED_0翻转
  56. LED_0.On(); //LED_0亮
  57. LED_0.Off(); //LED_0灭

  58. (&LED_0)->MakeOut(); //LED_0设置为输出
  59. (&LED_0)->Set(); //LED_0输出高
  60. (&LED_0)->Clr(); //LED_0输出低
  61. (&LED_0)->Toggle(); //LED_0翻转
  62. (&LED_0)->On(); //LED_0亮
  63. (&LED_0)->Off(); //LED_0灭


  64. LED_1.MakeOut(); //LED_1设置为输出
  65. LED_1.Set(); //LED_1输出高
  66. LED_1.Clr(); //LED_1输出低
  67. LED_1.Toggle(); //LED_1翻转
  68. LED_1.On(); //LED_1亮
  69. LED_1.Off(); //LED_1灭

  70. (&LED_1)->MakeOut(); //LED_1设置为输出
  71. (&LED_1)->Set(); //LED_1输出高
  72. (&LED_1)->Clr(); //LED_1输出低
  73. (&LED_1)->Toggle(); //LED_1翻转
  74. (&LED_1)->On(); //LED_1亮
  75. (&LED_1)->Off(); //LED_1灭

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

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

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

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

  90. }
汇编:
  1. RSEG CODE:CODE:NOROOT(1)
  2. // 65 void test(void)
  3. ??test:
  4. // 66 {
  5. // 67 LED_0.MakeOut(); //LED_0设置为输出
  6. SBI 0x11, 0x00
  7. // 68 LED_0.Set(); //LED_0输出高
  8. SBI 0x12, 0x00
  9. // 69 LED_0.Clr(); //LED_0输出低
  10. CBI 0x12, 0x00
  11. // 70 LED_0.Toggle(); //LED_0翻转
  12. LDI R16, 1
  13. IN R17, 0x12
  14. EOR R17, R16
  15. OUT 0x12, R17
  16. // 71 LED_0.On(); //LED_0亮
  17. SBI 0x12, 0x00
  18. // 72 LED_0.Off(); //LED_0灭
  19. CBI 0x12, 0x00
  20. // 73
  21. // 74 (&LED_0)->MakeOut(); //LED_0设置为输出
  22. SBI 0x11, 0x00
  23. // 75 (&LED_0)->Set(); //LED_0输出高
  24. SBI 0x12, 0x00
  25. // 76 (&LED_0)->Clr(); //LED_0输出低
  26. CBI 0x12, 0x00
  27. // 77 (&LED_0)->Toggle(); //LED_0翻转
  28. IN R17, 0x12
  29. EOR R17, R16
  30. OUT 0x12, R17
  31. // 78 (&LED_0)->On(); //LED_0亮
  32. SBI 0x12, 0x00
  33. // 79 (&LED_0)->Off(); //LED_0灭
  34. CBI 0x12, 0x00
  35. // 80
  36. // 81
  37. // 82 LED_1.MakeOut(); //LED_1设置为输出
  38. SBI 0x11, 0x01
  39. // 83 LED_1.Set(); //LED_1输出高
  40. SBI 0x12, 0x01
  41. // 84 LED_1.Clr(); //LED_1输出低
  42. CBI 0x12, 0x01
  43. // 85 LED_1.Toggle(); //LED_1翻转
  44. LDI R16, 2
  45. IN R17, 0x12
  46. EOR R17, R16
  47. OUT 0x12, R17
  48. // 86 LED_1.On(); //LED_1亮
  49. CBI 0x12, 0x01
  50. // 87 LED_1.Off(); //LED_1灭
  51. SBI 0x12, 0x01
  52. // 88
  53. // 89 (&LED_1)->MakeOut(); //LED_1设置为输出
  54. SBI 0x11, 0x01
  55. // 90 (&LED_1)->Set(); //LED_1输出高
  56. SBI 0x12, 0x01
  57. // 91 (&LED_1)->Clr(); //LED_1输出低
  58. CBI 0x12, 0x01
  59. // 92 (&LED_1)->Toggle(); //LED_1翻转
  60. IN R17, 0x12
  61. EOR R17, R16
  62. OUT 0x12, R17
  63. // 93 (&LED_1)->On(); //LED_1亮
  64. CBI 0x12, 0x01
  65. // 94 (&LED_1)->Off(); //LED_1灭
  66. SBI 0x12, 0x01
  67. // 95
  68. // 96 LED_2.MakeInHighImpedance(); //LED_2设置为高阻输入
  69. CBI 0x11, 0x02
  70. CBI 0x12, 0x02
  71. // 97 LED_2.MakeInPullUp(); //LED_2设置为上拉输入
  72. CBI 0x11, 0x02
  73. SBI 0x12, 0x02
  74. // 98 LED_2.MakeOutHigh(); //LED_2设置为输出高
  75. SBI 0x12, 0x02
  76. SBI 0x11, 0x02
  77. // 99 LED_2.MakeOutLow(); //LED_2设置为上拉输入
  78. CBI 0x12, 0x02
  79. SBI 0x11, 0x02
  80. // 100
  81. // 101 read=LED_2.ReadIn(); //读取LED_2引脚点品
  82. SBIS 0x10, 0x02
  83. RJMP ??test_1
  84. LDI R16, 1
  85. RJMP ??test_2
  86. ??test_1:
  87. LDI R16, 0
  88. ??test_2:
  89. STS `read`, R16
  90. // 102 read=LED_2.ReadDir(); //读取LED_2方向
  91. SBIS 0x11, 0x02
  92. RJMP ??test_3
  93. LDI R16, 1
  94. RJMP ??test_4
  95. ??test_3:
  96. LDI R16, 0
  97. ??test_4:
  98. STS `read`, R16
  99. // 103 read=LED_2.ReadOut(); //如果LED_2端口寄存器
  100. SBIS 0x12, 0x02
  101. RJMP ??test_5
  102. LDI R16, 1
  103. RJMP ??test_6
  104. ??test_5:
  105. LDI R16, 0
  106. ??test_6:
  107. STS `read`, R16
  108. // 104
  109. // 105 (&LED_2)->MakeInHighImpedance(); //LED_2设置为高阻输入
  110. CBI 0x11, 0x02
  111. CBI 0x12, 0x02
  112. // 106 (&LED_2)->MakeInPullUp(); //LED_2设置为上拉输入
  113. CBI 0x11, 0x02
  114. SBI 0x12, 0x02
  115. // 107 (&LED_2)->MakeOutHigh(); //LED_2设置为输出高
  116. SBI 0x12, 0x02
  117. SBI 0x11, 0x02
  118. // 108 (&LED_2)->MakeOutLow(); //LED_2设置为上拉输入
  119. CBI 0x12, 0x02
  120. SBI 0x11, 0x02
  121. // 109
  122. // 110 read=(&LED_2)->ReadIn(); //读取LED_2引脚点品
  123. SBIS 0x10, 0x02
  124. RJMP ??test_7
  125. LDI R16, 1
  126. RJMP ??test_8
  127. ??test_7:
  128. LDI R16, 0
  129. ??test_8:
  130. STS `read`, R16
  131. // 111 read=(&LED_2)->ReadDir(); //读取LED_2方向
  132. SBIS 0x11, 0x02
  133. RJMP ??test_9
  134. LDI R16, 1
  135. RJMP ??test_10
  136. ??test_9:
  137. LDI R16, 0
  138. ??test_10:
  139. STS `read`, R16
  140. // 112 read=(&LED_2)->ReadOut(); //如果LED_2端口寄存器
  141. SBIS 0x12, 0x02
  142. RJMP ??test_11
  143. LDI R16, 1
  144. RJMP ??test_12
  145. ??test_11:
  146. LDI R16, 0
  147. ??test_12:
  148. STS `read`, R16
  149. // 113
  150. // 114 }
  151. RET
 楼主| CC2530 发表于 2011-5-24 18:45 | 显示全部楼层
C:

  1. #include <intrinsics.h>
  2. #include <stddef.h>
  3. #include <ioavr.h>


  4. #ifndef _BV
  5. #define _BV(A)  (1U<<(A))
  6. #endif

  7. #ifndef __always_inline__
  8. #define __always_inline__  _Pragma("inline=forced") inline
  9. #endif

  10. typedef unsigned char uint8;


  11. #define AVR_GPIO_ASSIGN(A, B, C) \
  12. __always_inline__ static void   GPIO_##A##_Set(void)            {PORT##B |=  _BV(C);}\
  13. __always_inline__ static void   GPIO_##A##_Clr(void)            {PORT##B &= ~_BV(C);}\
  14. __always_inline__ static void   GPIO_##A##_MakeOut(void)        {DDR##B  |=  _BV(C);}\
  15. __always_inline__ static void   GPIO_##A##_MakeIn(void)         {DDR##B  &= ~_BV(C);}\
  16. __always_inline__ static void   GPIO_##A##_MakeOutHigh(void)    {GPIO_##A##_Set(); GPIO_##A##_MakeOut();}\
  17. __always_inline__ static void   GPIO_##A##_MakeOutLow(void)     {GPIO_##A##_Clr(); GPIO_##A##_MakeOut();}\
  18. __always_inline__ static void   GPIO_##A##_MakeInHighImpedance(void)  {DDR##B &= ~_BV(C); PORT##B &= ~_BV(C);}\
  19. __always_inline__ static void   GPIO_##A##_MakeInPullUp(void)   {DDR##B &= ~_BV(C); PORT##B |=  _BV(C);}\
  20. __always_inline__ static void   GPIO_##A##_Toggle(void)         {PORT##B ^= _BV(C);}\
  21. __always_inline__ static uint8  GPIO_##A##_ReadIn(void)         {return ((PIN##B & _BV(C)) != 0);}\
  22. __always_inline__ static uint8  GPIO_##A##_ReadOut(void)        {return ((PORT##B & _BV(C)) != 0);}\
  23. __always_inline__ static uint8  GPIO_##A##_ReadDir(void)        {return ((DDR##B & _BV(C)) != 0);}\
  24. __always_inline__ static uint8  GPIO_##A##_Read(void)           {return GPIO_##A##_ReadIn();}\
  25. __always_inline__ static void   GPIO_##A##_Out(uint8 x)         {(x)?(GPIO_##A##_Set()):(GPIO_##A##_Clr());}\
  26. __always_inline__ static uint8  GPIO_##A##_IsOutHigh(void)      {return GPIO_##A##_ReadOut();}\
  27. __always_inline__ static uint8  GPIO_##A##_IsOutLow(void)       {return !GPIO_##A##_ReadOut();}

  28. #define AVR_GPIO_ASSIGN_POLARITY(A, B, C,X) \
  29. AVR_GPIO_ASSIGN(A, B, C)\
  30. __always_inline__ static void   GPIO_##A##_On(void)             { (X)?(GPIO_##A##_Set()):(GPIO_##A##_Clr());}\
  31. __always_inline__ static void   GPIO_##A##_Off(void)            {(!X)?(GPIO_##A##_Set()):(GPIO_##A##_Clr());}\
  32. __always_inline__ static void   GPIO_##A##_MakeOutOn(void)      {GPIO_##A##_On();GPIO_##A##_MakeOut();}\
  33. __always_inline__ static void   GPIO_##A##_MakeOutOff(void)     {GPIO_##A##_Off();GPIO_##A##_MakeOut();}\
  34. __always_inline__ static uint8  GPIO_##A##_IsOn(void)           {return  (X)?GPIO_##A##_IsOutHigh():GPIO_##A##_IsOutLow();}\
  35. __always_inline__ static uint8  GPIO_##A##_IsOff(void)          {return (!X)?GPIO_##A##_IsOutHigh():GPIO_##A##_IsOutLow();}

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


  40. volatile uint8 read;

  41. void test(void)
  42. {
  43.   GPIO_LED_0_MakeOut();         //LED_0设置为输出
  44.   GPIO_LED_0_Set();             //LED_0输出高
  45.   GPIO_LED_0_Clr();             //LED_0输出低
  46.   GPIO_LED_0_Toggle();          //LED_0翻转
  47.   GPIO_LED_0_On();              //LED_0亮
  48.   GPIO_LED_0_Off();             //LED_0灭
  49.    
  50.    
  51.   GPIO_LED_1_MakeOut();         //LED_1设置为输出
  52.   GPIO_LED_1_Set();             //LED_1输出高
  53.   GPIO_LED_1_Clr();             //LED_1输出低
  54.   GPIO_LED_1_Toggle();          //LED_1翻转
  55.   GPIO_LED_1_On();              //LED_1亮
  56.   GPIO_LED_1_Off();             //LED_1灭
  57.    
  58.   
  59.   GPIO_LED_2_MakeInHighImpedance();  //LED_2设置为高阻输入
  60.   GPIO_LED_2_MakeInPullUp();         //LED_2设置为上拉输入
  61.   GPIO_LED_2_MakeOutHigh();          //LED_2设置为输出高
  62.   GPIO_LED_2_MakeOutLow();           //LED_2设置为上拉输入
  63.   
  64.   read=GPIO_LED_2_ReadIn();          //读取LED_2引脚点品  
  65.   read=GPIO_LED_2_ReadDir();         //读取LED_2方向
  66.   read=GPIO_LED_2_ReadOut();         //如果LED_2端口寄存器
  67.   
  68. }

  69. 汇编:
  70. [code]
  71.         RSEG CODE:CODE:NOROOT(1)
  72. //   52 void test(void)
  73. test:
  74. //   53 {
  75. //   54   GPIO_LED_0_MakeOut();         //LED_0设置为输出
  76.         SBI     0x11, 0x00
  77. //   55   GPIO_LED_0_Set();             //LED_0输出高
  78.         SBI     0x12, 0x00
  79. //   56   GPIO_LED_0_Clr();             //LED_0输出低
  80.         CBI     0x12, 0x00
  81. //   57   GPIO_LED_0_Toggle();          //LED_0翻转
  82.         LDI     R16, 1
  83.         IN      R17, 0x12
  84.         EOR     R17, R16
  85.         OUT     0x12, R17
  86. //   58   GPIO_LED_0_On();              //LED_0亮
  87.         SBI     0x12, 0x00
  88. //   59   GPIO_LED_0_Off();             //LED_0灭
  89.         CBI     0x12, 0x00
  90. //   60   
  91. //   61   
  92. //   62   GPIO_LED_1_MakeOut();         //LED_1设置为输出
  93.         SBI     0x11, 0x01
  94. //   63   GPIO_LED_1_Set();             //LED_1输出高
  95.         SBI     0x12, 0x01
  96. //   64   GPIO_LED_1_Clr();             //LED_1输出低
  97.         CBI     0x12, 0x01
  98. //   65   GPIO_LED_1_Toggle();          //LED_1翻转
  99.         LDI     R16, 2
  100.         IN      R17, 0x12
  101.         EOR     R17, R16
  102.         OUT     0x12, R17
  103. //   66   GPIO_LED_1_On();              //LED_1亮
  104.         CBI     0x12, 0x01
  105. //   67   GPIO_LED_1_Off();             //LED_1灭
  106.         SBI     0x12, 0x01
  107. //   68   
  108. //   69   
  109. //   70   GPIO_LED_2_MakeInHighImpedance();  //LED_2设置为高阻输入
  110.         CBI     0x11, 0x02
  111.         CBI     0x12, 0x02
  112. //   71   GPIO_LED_2_MakeInPullUp();         //LED_2设置为上拉输入
  113.         CBI     0x11, 0x02
  114.         SBI     0x12, 0x02
  115. //   72   GPIO_LED_2_MakeOutHigh();          //LED_2设置为输出高
  116.         SBI     0x12, 0x02
  117.         SBI     0x11, 0x02
  118. //   73   GPIO_LED_2_MakeOutLow();           //LED_2设置为上拉输入
  119.         CBI     0x12, 0x02
  120.         SBI     0x11, 0x02
  121. //   74   
  122. //   75   read=GPIO_LED_2_ReadIn();          //读取LED_2引脚点品  
  123.         SBIS    0x10, 0x02
  124.         RJMP    ??test_0
  125.         LDI     R16, 1
  126.         RJMP    ??test_1
  127. ??test_0:
  128.         LDI     R16, 0
  129. ??test_1:
  130.         STS     `read`, R16
  131. //   76   read=GPIO_LED_2_ReadDir();         //读取LED_2方向
  132.         SBIS    0x11, 0x02
  133.         RJMP    ??test_2
  134.         LDI     R16, 1
  135.         RJMP    ??test_3
  136. ??test_2:
  137.         LDI     R16, 0
  138. ??test_3:
  139.         STS     `read`, R16
  140. //   77   read=GPIO_LED_2_ReadOut();         //如果LED_2端口寄存器
  141.         SBIS    0x12, 0x02
  142.         RJMP    ??test_4
  143.         LDI     R16, 1
  144.         RJMP    ??test_5
  145. ??test_4:
  146.         LDI     R16, 0
  147. ??test_5:
  148.         STS     `read`, R16
  149. //   78   
  150. //   79 }
  151.         RET
[/code]
 楼主| CC2530 发表于 2011-5-24 18:49 | 显示全部楼层
IAR工程

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
murex 发表于 2011-5-24 21:57 | 显示全部楼层
IAR还不会用,哈
hotpower 发表于 2011-5-25 01:15 | 显示全部楼层
欢迎加入 LOOK阵营
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

0

主题

262

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部