Microchip
直播中

李焰

7年用户 205经验值
私信 关注
[问答]

PIC16F1503在memcpy上停止

大家好,很难找出为什么我的PIC16F503是拖延(冻结,崩溃?)在MimcPy语句上。我没有调试头,所以我不得不依赖基本的调试和模拟器。我通过把一个LATA写在一个LED上,直到它不再工作,把它缩小到这个语句上。在模拟器里,我没有看到任何问题,它运行良好,完全符合我的期望。这发生在我的init函数中,这是第一个主要的东西,所以应该有。在这之前没有任何事情发生。想知道你们这里的专家是否能给我一些关于它停止的想法。我想可能是一个中断,但即使是GIE残疾人,也无法通过这个声明。谢谢!

以上来自于百度翻译


      以下为原文

    Hello all,

Having a hard time figuring out why my PIC16F1503 is stalling (freezing, crashing?) on a memcpy statement. I don't have a debug header, so I'm forced to rely on basic debugging and the simulator. I narrowed it down to this statement by moving a LATA write around that turns on an LED until it no longer worked.

In the simulator I'm not seeing any issues, it runs fine and does exactly what I expect it to.

This happens within my Init function, which is the very first thing in main so there shouldn't be anything executing before this.

Wondering if any of you experts here could give me some ideas on what could be causing it to stop. I thought maybe an interrupt, but even with GIE disabled it fails to get past that statement.

Thank you!

#include
#include
#include

extern volatile char lcd_buffer[21];

void Init(void){
    // Set Processor Frequency
    // OSCCON - Oscillator Control Register

    OSCCON = 0b01101000;

    // Set Data Port Input/Output
    ANSELA = 0x00; // Turn off Analog Input functionality
    LATA = 0x00; // Set default Port A output values
    TRISA = 0x23; // Set bits 2 and 4 as output
   
    ANSELC = 0x00; // Turn off Analog Input functionality
    TRISC = 0xFF; // Set all of Port C as input
   
    // Configure I2C Registers
   
    // SSP1STAT - SSP Status Register
    SSP1CON1 = 0x28;
   
    // SSP1CON2 - SSP Control Register 2
    SSP1CON3 = 60;
   
    // SSP1ADD - MSSP Address and Baud Rate Register
    SSP1ADD = 0x09;
   
    // Enable MSSP (I2C) Interrupts
    PIE1bits.SSP1IE = 1;
   
    // Enable Global Interrupts
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
   
    // Initialize the LCD
    const uint8_t lcd_init1[] = {0x00,0x38,0x39,0x14,0x78,0x5E,0x6D};
    memcpy(lcd_buffer,lcd_init1,7);

    // More code follows, but this is where the LATA command fails to execute

}

回帖(8)

tijing忽忽

2018-11-7 09:16:43
好的,你有一个声明LCDYBuff:但是这个变量的定义在哪里?基本上,声明(任何时候使用Extn都是声明)不分配内存,只有定义才这样做。你需要的地方:

以上来自于百度翻译


      以下为原文

    OK you have a declaration for lcd_buffer:
extern volatile char lcd_buffer[21];
but where is the definition of this variable?
Basically, declarations (anytime you use extern it is a declaration) DO NOT allocate memory only the definition does that. Somewhere you need:
volatile char lcd_buffer[21];
 
举报

杨玲

2018-11-7 09:26:42
LCDY缓冲区定义在哪里?我不希望你的代码链接到它的当前状态。

以上来自于百度翻译


      以下为原文

    Where is lcd_buffer defined?  I wouldn't expect your code to link in its current state.
举报

廉鼎琮

2018-11-7 09:39:48
init函数在它自己的C文件中。LCDAL缓冲区在main中定义,以及ISR使用的其他全局变量。这里是主文件。

以上来自于百度翻译


      以下为原文

    The init function is in it's own c file.
 
lcd_buffer is defined in main, along with some other global variables used by the ISR.
 
Here is the main file.
 
 // Include PIC16F1503 CONFIG register settings
// These control clock selection, watchdog disable, etc
#include "pic16f1503config.h"

// Compiler include file
#include

// C Standard Includes
#include
#include

// Project Specific Includes
#include "Init.h"
#include "lcd_funcs.h"
#include "AlarmClock.h"


// Global Variables
volatile l_state lcd_state;
volatile uint8_t msg_length;
volatile unsigned char *lcd_msg;
uint8_t i2c_addr;
volatile char lcd_buffer[21];

void main(void) {
    // Initialization of MCU & peripherals
    Init();
    
    while(1){
        // The main loop of the program runs forever
        lcd_buffer[0]=0x40;
        const char testmsg[] = "This is a test";
        memcpy(lcd_buffer+1,testmsg,14);
        send2lcd(lcd_buffer,15,lcd_w);
        while(1){
            // Basically stop for test
        }
    }
    return;
}

void interrupt pic16_int (void) {
    if(SSP1IF == 1){
        // If MSSP module generated the interrupt, clear the flag and process
        LATA = 0x10;
        SSP1IF = 0;
        switch(lcd_state) {
            case lcd_idle:
                // Do Nothing
                break;
            case lcd_start:
                // Start Condition Completed, send address
                SSP1BUF = i2c_addr;
                // Then go to next state
                if(i2c_addr & 0x01){
                    // LSB '1' = TX
                    lcd_state = lcd_rx;
                } else {
                    // LSB '0' = RX
                    lcd_state = lcd_tx;
                }
                break;
            case lcd_tx:
                // Loading buffer starts transmission
                SSP1BUF = *lcd_msg;
                lcd_msg++;
                msg_length--;
                if(msg_length == 0){
                    lcd_state = lcd_stop;
                }
                break;
            case lcd_rx:
                // Grab received byte
                break;
            case lcd_stop:
                // Set Stop Bit
                SSP1CON2bits.PEN = 1;
                lcd_state = lcd_finish;
                break;
            case lcd_finish:
                // I2C Transaction is completed, go to idle
                lcd_state = lcd_idle;
        }
    }
    return;
}
举报

tijing忽忽

2018-11-7 09:46:08
只要你不需要这个:

以上来自于百度翻译


      以下为原文

    just FYI you do not need this:
#include
举报

更多回帖

发帖
×
20
完善资料,
赚取积分