gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 08:13:32 24 4
gpt4 key购买 nike

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

我的目标是每 100 毫秒(通过定时器 1 设置)获取 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] = '\0'; // 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 ***************************************************************/

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

最佳答案

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

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

  1. 将数据填充到数组中的代码不正确。下面的代码从位置 arrray[0]array[1] 到 max 依次填充数组。

定时器应该这样修改

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] = '\0'; // Empty array
} //rof
} //fi
}
}

关于c - 将 PORTD 值存储在 pic18f452 的数组中 (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37294009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com