GPIO使用实例

本实例程序中,我们将测试一个GPIO管脚的中断触发:为管脚设置中断服务函数,触发方式为边沿触发,然后通过交替写高低电平到管脚,产生电平波动,制造触发条件,观察中断服务函数的执行。

首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300某开发板,GPIO管脚选择GPIO10_3,换算成GPIO号为83。

读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。

  1. #include"gpio_if.h"
  2. #include"hdf_log.h"
  3. #include"osal_irq.h"
  4. #include"osal_time.h"
  5. staticuint32_t g_irqCnt;
  6. /* 中断服务函数*/
  7. staticint32_tTestCaseGpioIrqHandler(uint16_t gpio,void*data)
  8. {
  9. HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data);
  10. g_irqCnt++;/* 如果中断服务函数触发执行,则将全局中断计数加1 */
  11. returnGpioDisableIrq(gpio);
  12. }
  13. /* 测试用例函数 */
  14. staticint32_tTestCaseGpioIrqEdge(void)
  15. {
  16. int32_t ret;
  17. uint16_t valRead;
  18. uint16_t mode;
  19. uint16_t gpio =83;/* 待测试的GPIO管脚号 */
  20. uint32_t timeout;
  21. /* 将管脚方向设置为输出 */
  22. ret =GpioSetDir(gpio, GPIO_DIR_OUT);
  23. if(ret != HDF_SUCCESS){
  24. HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret);
  25. return ret;
  26. }
  27. /* 先禁止该管脚中断 */
  28. ret =GpioDisableIrq(gpio);
  29. if(ret != HDF_SUCCESS){
  30. HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret);
  31. return ret;
  32. }
  33. /* 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发 */
  34. mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING;
  35. HDF_LOGE("%s: mode:%0x\n", __func__, mode);
  36. ret =GpioSetIrq(gpio, mode,TestCaseGpioIrqHandler, NULL);
  37. if(ret != HDF_SUCCESS){
  38. HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret);
  39. return ret;
  40. }
  41. /* 使能此管脚中断 */
  42. ret =GpioEnableIrq(gpio);
  43. if(ret != HDF_SUCCESS){
  44. HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret);
  45. (void)GpioUnSetIrq(gpio);
  46. return ret;
  47. }
  48. g_irqCnt =0;/* 清除全局计数器 */
  49. timeout =0;/* 等待时间清零 */
  50. /* 等待此管脚中断服务函数触发,等待超时时间为1000毫秒 */
  51. while(g_irqCnt <=0&& timeout <1000){
  52. (void)GpioRead(gpio,&valRead);
  53. (void)GpioWrite(gpio,(valRead == GPIO_VAL_LOW)? GPIO_VAL_HIGH : GPIO_VAL_LOW);
  54. HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout);
  55. OsalMDelay(200);/* wait for irq trigger */
  56. timeout +=200;
  57. }
  58. (void)GpioUnSetIrq(gpio);
  59. return(g_irqCnt >0)? HDF_SUCCESS : HDF_FAILURE;
  60. }