问答

汇集网友智慧,解决技术难题

21ic问答首页 - 关于MPLAB的问题

单片机

关于MPLAB的问题

JayWong19882021-12-08
各位大神好,我是一个加拿大的电子系的留学生,我有一个实验需要写一个MPLAB的单机片,我硬件已连接显示屏,keypad,LM60温度感应器,我用的IC是p24HJ128GP502,我的C语言编程不是太好,所以请各位大神帮帮我吧!它的要求如下:我如何在while loop里添加一下的功能呢?
1. 上电自检。红色LED闪烁三次。好的消息。
2. 显示选项:1)读取,2)保存,3)召回和4)清除。
3. 要求选择按1,读取传感器读数并在LCD上显示读数。
4. 眨了一次。按2保存传感器读数,并确认保存在LCD上。
5. 眨了两次。按3来回忆一个保存的阅读。询问阅读数字。
6. 按4清除不保存的读数。
7. 眨了一次。完成任何选择后,返回到显示选项屏幕。
这是我的代码,我尝试了把它的要求写进去,但都失败。
#include "pic24_all.h"
#include <stdio.h>

# define RS_HIGH()        (_LATB9 = 1)
# define RS_LOW()         (_LATB9 = 0)
# define CONFIG_RS()      CONFIG_RB9_AS_DIG_OUTPUT()

# define RW_HIGH()        (_LATB13 = 1)
# define RW_LOW()         (_LATB13 = 0)
# define CONFIG_RW()      CONFIG_RB13_AS_DIG_OUTPUT()

# define E_HIGH()         (_LATB14 = 1)
# define E_LOW()          (_LATB14 = 0)
# define CONFIG_E()       CONFIG_RB14_AS_DIG_OUTPUT()
# define LED (_LATB14)

# define LCD4O          (_LATB5)
# define LCD5O          (_LATB6)
# define LCD6O          (_LATB7)
# define LCD7O          (_LATB8)
# define LCD7I          (_RB8)

# define CONFIG_LCD4_AS_INPUT() CONFIG_RB5_AS_DIG_INPUT()
# define CONFIG_LCD5_AS_INPUT() CONFIG_RB6_AS_DIG_INPUT()
# define CONFIG_LCD6_AS_INPUT() CONFIG_RB7_AS_DIG_INPUT()
# define CONFIG_LCD7_AS_INPUT() CONFIG_RB8_AS_DIG_INPUT()

# define CONFIG_LCD4_AS_OUTPUT() CONFIG_RB5_AS_DIG_OUTPUT()
# define CONFIG_LCD5_AS_OUTPUT() CONFIG_RB6_AS_DIG_OUTPUT()
# define CONFIG_LCD6_AS_OUTPUT() CONFIG_RB7_AS_DIG_OUTPUT()
# define CONFIG_LCD7_AS_OUTPUT() CONFIG_RB8_AS_DIG_OUTPUT()

#define GET_BUSY_FLAG()  (LCD7I)


//Pulse the E clock, 1 us delay around edges for
//setup/hold times
void pulseE(void) {
  DELAY_US(1);
  E_HIGH();
  DELAY_US(1);
  E_LOW();
  DELAY_US(1);
}



  uint8_t u8_wdtState;
  if (u8_CheckBusy) {
    RS_LOW();            //RS = 0 to check busy
    // check busy
    configBusAsInLCD();  //set data pins all inputs
    u8_wdtState = _SWDTEN;  //save WDT enable state
    CLRWDT();          //clear the WDT timer
    _SWDTEN = 1;            //enable WDT to escape infinite wait
    do {
      E_HIGH();
      DELAY_US(1);  // read upper 4 bits
      u8_BusyFlag = GET_BUSY_FLAG();
      E_LOW();
      DELAY_US(1);
      pulseE();              //pulse again for lower 4-bits
    } while (u8_BusyFlag);
    _SWDTEN = u8_wdtState;   //restore WDT enable state
  } else {
    DELAY_MS(10); // don't use busy, just delay
  }
  configBusAsOutLCD();
  if (u8_DataFlag) RS_HIGH();   // RS=1, data byte
  else    RS_LOW();             // RS=0, command byte
  outputToBusLCD(u8_Cmd >> 4);  // send upper 4 bits
  pulseE();
  if (u8_Send8Bits) {
    outputToBusLCD(u8_Cmd);     // send lower 4 bits
    pulseE();
  }
}
// Initialize the LCD, modify to suit your application and LCD
void initLCD() {
  DELAY_MS(50);          //wait for device to settle
  writeLCD(0x20,0,0,0); // 4 bit interface
  writeLCD(0x28,0,0,1); // 2 line display, 5x7 font
  writeLCD(0x28,0,0,1); // repeat
  writeLCD(0x06,0,0,1); // enable display
  writeLCD(0x0C,0,0,1); // turn display on; cursor, blink is off
  writeLCD(0x01,0,0,1); // clear display, move cursor to home
  DELAY_MS(3);
}
//Output a string to the LCD
void outStringLCD(char *psz_s) {
  while (*psz_s) {
    writeLCD(*psz_s, 1, 1,1);
    psz_s++;
  }
}
#define C0 _RB12
#define C1 _RB2
#define C2 _RB3
#define C3 _RA2
static inline void CONFIG_COLUMN() {
  CONFIG_RB12_AS_DIG_INPUT();
  ENABLE_RB12_PULLUP();
  CONFIG_RB2_AS_DIG_INPUT();
  ENABLE_RB2_PULLUP();
  CONFIG_RB3_AS_DIG_INPUT();
  ENABLE_RB3_PULLUP();
  CONFIG_RA2_AS_DIG_INPUT();
  ENABLE_RA2_PULLUP();
}
#define R0 _RA3
#define R1 _RB4
#define R2 _RA4
#define CONFIG_R0_DIG_OUTPUT() CONFIG_RA3_AS_DIG_OUTPUT()
#define CONFIG_R1_DIG_OUTPUT() CONFIG_RB4_AS_DIG_OUTPUT()
#define CONFIG_R2_DIG_OUTPUT() CONFIG_RA4_AS_DIG_OUTPUT()
void CONFIG_ROW() {

#define NUM_ROWS 3
#define NUM_COLS 4
const uint8_t au8_keyTable[NUM_ROWS][NUM_COLS] = {
  {'1', '4', '7', '*'},
  {'2', '5', '8', '0'},
  {'3', '6', '9', '#'}
};
#define KEY_PRESSED() (!C0 || !C1 || !C2 || !C3)   //any low
#define KEY_RELEASED() (C0 && C1 && C2 && C3)  //all high

//#define temp_c
#define VREF 3.3
int main (void) {
  configBasic(HELLO_MSG);
  /** PIO config ******/
  configKeypad();
  /** Configure the Timer */
  configTimer3();
  configControlLCD();      //configure the LCD control lines
  initLCD();               //initialize the LCD
  uint16_t u16_adcVal;
  float f_adcVal;
  char buff[50];
  CONFIG_RA0_AS_ANALOG();
  configADC1_ManualCH0(RA0_AN, 31, 0);
while (1) {
   // u16_adcVal = convertADC1();   //get ADC value
   // f_adcVal = u16_adcVal;
   // f_adcVal = f_adcVal/1024.0 * VREF;  //convert to float in range 0.0 to VREF
   // printf("ADC input: %4.2f V (0x%04x),T=%7,4fc\n", (double) f_adcVal, u16_adcVal);
   //sprintf(buff, "ADC input: %4.2f V (0x%04x),T=%7,4fc\n", (double) f_adcVal, u16_adcVal);
   // writeLCD(0x01,0,1,1);   
   // outStringLCD(buff);   
    }
  {
  } // end while (1)
}



回答 +关注 2
3274人浏览 2人回答问题 分享 举报
2 个回答
  • 你的程序架构是有问题的,一般情况,建议使用如下的架构:

    1. 在主main函数里面,while循环之前,将所有的事件进行初始化;
    2. while循环你就可以增加你的功能,可以是状态机,也可以是按照你的要求调用定时器去控制时间片;
    3. 如果有额外的中断任务,例如不定时过来的按键任务,就在中断里面进行扫描(当然也可以使用轮询的形式进行进行按键扫描,都要放到主循环里面)
    4. 这样你把每个状态进行系统的调度和切换,程序会看的更加的简洁和明了的。
    JayWong1988 2021-12-13 05:57 回复TA
    首先谢谢你,可不可以给我例子说明,感激不尽。 
  • 一句话,就是在定时器里置各种标志位,然后在主循环里刷新,执行任务和清标志位

您需要登录后才可以回复 登录 | 注册