将 PORTD 值存储在 pic18f452 的数组中 (C)

Storing PORTD value in array on pic18f452 (C)

我正在 Proteus 上开发 PIC18F452,正在寻求一些建议。

我的objective是每隔100ms(通过timer1设置)获取PORTDbits.RD0(设置为输入)的值,存入8位数组。该帧稍后将通过 SPI 发送到从机。

目前我只实现了我认为是数组的填充和位移。可悲的是,当我开始模拟时,只有数组的某个位在某些时候包含 PORTDbits.RD0.

的值

如果有人有什么想法可以提供帮助,那就太好了:D

这是我的代码

/* CONFIG *******************************************************************/
#pragma config PWRT  = ON    // Power-up Timer
#pragma config OSC   = HS    // High-Speed Oscillator
#pragma config LVP   = OFF   // Low-Voltage In-Circuit Serial Programming
#pragma config DEBUG = ON    //

/* INCLUDES *****************************************************************/
#include "project_config.h"  // All headers inclusion

/* MACROS *******************************************************************/
#define nop() {_asm nop _endasm}

/* DEFINES ******************************************************************/
#define SIZE 8

/* FUNCTIONS PROTOTYPES *****************************************************/
void main(void);

void isr_config(void);
void io_config(void);

void timer1_config(void);
void timer1_isr(void);

/* PROTOTYPES ***************************************************************/

/* VARIABLES DEFINITION *****************************************************/
unsigned int filling_cnt = 0; 

/* MAIN *********************************************************************/
void main(void) {
    unsigned char array[SIZE]; 
    unsigned int index = 0; 
    int j; 

    /// Initialization
    io_config();
    timer1_config();
    isr_config();

    /// Interruption
    timer1_isr();

    /// Data acquisiton
    while(1){
        array[index] = PORTDbits.RD0;          // Read RD0 and save in array        
        for(index = 0; index < SIZE; index++){ // Fill array
            array[index] = array[index+1];     // shifting n_value to insert n+1_value
            //printf("%s\n", array);
         } //rof

         filling_cnt++;                         // Array counter for filling control

         if(filling_cnt > SIZE){                  // Reached the end of array ?
            index = 0;                         // Reset counter
            printf("%s\n", array);             // Send data to terminal
            for (j=0; j<SIZE; j++){
                array[j] = '[=10=]';               // Empty array
            } //rof
         } //fi
    }
}

/* FUNCTIONS ****************************************************************/
/// Configurations
void timer1_config(void) {
    T1CONbits.RD16 = 1;    // Timer/Counter 8-bits/16-bits Control bit: 0=8-bits / 1=16-bits
    T1CONbits.T1CKPS1 = 1; // Prescaler
    T1CONbits.T1CKPS0 = 1; //   1 = 0b00
                           //   2 = 0b01
                           //   4 = 0b10
                           //   8 = 0b11
    T1CONbits.T1OSCEN = 1; // Timer1 Oscillator shut off
    T1CONbits.TMR1CS = 0;  // Timer1 Clock Source Select bit
                           //   0 = Internal Clock (Fosc/4)
                           //   1 = Transition on T1CKI pin
    T1CONbits.TMR1ON = 1;  // Timer1 On/Off Control bit
                           //   1 = Enables Timer1
                           //   0 = Stops Timer1
    TMR1H=0x0B;            // Preset timer1 value for MSB register
    TMR1L=0xDB;            // Preset timer1 value for LSB register
                           // to get a 100ms delay
}

void isr_config(void) {
    PIE1bits.TMR1IE = 1;   // Enable Timer1 interrupts
    PIR1bits.TMR1IF = 0;   // Clear Timer1 interrupt flag
    IPR1bits.TMR1IP = 1;   // Non high priority interrupt

    RCONbits.IPEN   = 1;   // Interrupt High level

    INTCONbits.PEIE = 1;   // All peripherals interrutps verified
    INTCONbits.GIE  = 1;   // All interrupts verified
}

void io_config(void) {
    TRISB = 0x00;          // PORTB as output
    TRISDbits.TRISD0 = 1;  // COMP_OUT as input
    TRISDbits.TRISD1 = 0;  // DATA as output
}

/// Interruptions
#pragma code highVector = 0x08 //lowVector = 0x18
void InterruptHigh (void) {
   _asm
   goto timer1_isr
   _endasm
}
#pragma code

#pragma interrupt timer1_isr
void timer1_isr(void) {
     if (PIR1bits.TMR1IF == 1) {  // check that timer1 overflow is reason for ISR.
                                  // even though there is only one Interrupt source
                                  // trigger enabled, it is good programming practice to
                                  // test why we have arrived at the ISR.
        PIR1bits.TMR1IF = 0; // Timer1 interrupt flag clear

        TMR1H = 0x0B;        // Preset timer1 value for MSB register
        TMR1L = 0xDC;        // Preset timer1 value for LSB register
                             // with a 20MHz xtal, Timer1 Prescalar set to /8
                             // decimal 3036 (0x0B 0xDC) is the counter start point
                             // which will result in Timer1 overflow 1 per 100ms
                             // 65536 - 3036 = 62500 cycles
                             // 10 interrupts per second

        LATBbits.LATB4 = !LATBbits.LATB4; // invert the condition of LED to show program
                                          // has entered the Interrupt routine
        PORTDbits.RD1 = !PORTDbits.RD1;   // invert the condition of DATA to show program
                                          // has entered the Interrupt routine                              
     } //fi
}

/* EOF main.c ***************************************************************/

如果此消息中有任何遗漏或不清楚的地方,请随时告诉我。我会尽力添加细节或重新考虑我的 post 以促进理解。 提前致谢 ;)

  1. 在 main 函数中有一个无限循环,它在两次采集之间没有任何延迟地运行。您需要的是两次读取 PORTD 之间有 100ms 的延迟。

您可以做的是引入一个全局标志。这在定时器子程序中设置,并在 main 中清除。

  1. 将数据填充到数组中的代码不正确。下面的代码按顺序从位置 arrray[0]array[1] 到最大值填充数组。

计时器应该这样修改

void timer1_isr(void) {
    if (PIR1bits.TMR1IF == 1) {
        blTimeOverFlag = 1;
        // Other code here
    }
}

主函数循环如下

while(1){
  if (blTimeOverFlag == 1)
  {   
    blTimeOverFlag = 0;
    array[filling_cnt] = PORTDbits.RD0;          // Read RD0 and save in array        
     filling_cnt++;                         // Array counter for filling control

     if(filling_cnt >= SIZE){                  // Reached the end of array ?
        filling_cnt = 0;
        printf("%s\n", array);             // Send data to terminal
        for (j=0; j<SIZE; j++){
            array[j] = '[=11=]';               // Empty array
        } //rof
     } //fi
  }
}