首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ESP32 FreeRTOS如何使用MCP23017避免硬件冲突

ESP32 FreeRTOS如何使用MCP23017避免硬件冲突
EN

Stack Overflow用户
提问于 2022-02-16 06:22:32
回答 1查看 298关注 0票数 0

我有一个ESP32,使用MCP23017集成电路,使用旋转编码器,完美地处理中断和任务。然后,我添加到一个连接到L293D的MCP23017上,运行良好。

当步进电机工作时,当我与旋转编码器交互时,问题就会发生。ESP32重新启动,我确信原因是这两个任务都希望同时访问MCP23017硬件。

因为MCP23017使用的是Sempahore:

代码语言:javascript
运行
复制
SemaphoreHandle_t rotaryISRSemaphore = nullptr;
// MCP23017
Adafruit_MCP23017 mcp;
....

void setup(){
   ....
   rotaryISRSemaphore = xSemaphoreCreateBinary();
   mcp.begin(1);      // use default address 0

   xTaskCreatePinnedToCore(&rotaryReaderTask, "rotary reader", 2048, NULL, 20, NULL, 1);
   attachInterrupt(esp32IntPin, intCallBack, FALLING);
  
   xTaskCreate(stepperMotor,"Stepper Motor",2048, NULL, 1, NULL);
}

// The int handler will just signal that the int has happened
// we will do the work from a task.
void IRAM_ATTR intCallBack() {
   //Serial.println("intCallback");
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR(rotaryISRSemaphore, &xHigherPriorityTaskWoken);
    if(xHigherPriorityTaskWoken) {
        portYIELD_FROM_ISR ();
    }
}

void rotaryReaderTask(void* pArgs) {
    (void)pArgs;
    Serial.println("Started rotary reader task.");
    while(true) {
        if(xSemaphoreTake(rotaryISRSemaphore, portMAX_DELAY) == pdPASS) {
        
            handleInterrupt();
         
        }

void handleInterrupt(){

    //Read the entire state when the interrupt occurred
    ....
    // Here some work to do with the MCP23017
}

void loop() {


}

int stepperValues[4][4] = {{HIGH,LOW,HIGH,LOW},{LOW,HIGH,HIGH,LOW},{LOW,HIGH,LOW,HIGH}, {HIGH,LOW,LOW,HIGH}};

void stepperMotor(void * params){
  (void) params;
  for(;;){ 
         if(!stopStepper){
        for ( int i = 0; i < 4; ++i ) {

      // loop through columns of current row
        mcp.digitalWrite(10, stepperValues[i][0]);
        mcp.digitalWrite(11, stepperValues[i][1]);
        mcp.digitalWrite(12, stepperValues[i][2]);
        mcp.digitalWrite(13, stepperValues[i][3]);
       } 
    }
    vTaskDelay(10 / portTICK_PERIOD_MS);
  }
}

有关于如何避免ESP32重新启动问题的线索吗?

EN

回答 1

Stack Overflow用户

发布于 2022-02-16 07:13:25

当您拥有需要由多个任务访问的共享资源时,需要使用互斥保护资源。

如果完全控制代码,最好的选择是向I2C总线添加互斥,因为I2C总线上可能有需要从多个任务访问的其他设备。

如果您不能修改I2C代码,并且MCP23017是总线上唯一的设备,那么您可以编写一些包装函数/类,在访问MCP23017之前锁定互斥对象,然后再解锁它。

请注意,您不能在ISR中使用互斥,因此您的代码可能需要进一步重构,以便只从任务上下文访问设备。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71137216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档