|
XC8+PIC16+I2C |
|
|
|
May 29 2014, 07:09
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 29-01-08
Из: Нижний Новгород
Пользователь №: 34 535

|
Добрый день, господа! Прошу Вашей помощи.
Код #include <../../../../../../../../include/xc.h> #include <../../../../../../include/pic16f1518.h>
// #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF.
// CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable bit (VCAP pin function disabled) #pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#define _XTAL_FREQ 16000000 #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
unsigned char Tmp;
main(void) { OSCCON = 0b01111010; // Internal OSC @ 16MHz SSPCON1=0b00101000; //I2C master SSPCON3bits.SDAHT = 1; // Minimum of 300 ns hold time on SDA // after the falling edge of SCL SSPSTAT=0b10000000; //slew rate control disabled SSPADD=0x27; //100 kHz SSPIF = 0; // Clear the serial port interrupt flag BCLIF = 0; // Clear the bus coll interrupt flag BCLIE = 1; // Enable bus collision interrupts SSPIE = 1; // Enable serial port interrupts PEIE = 1; // Enable peripheral interrupts GIE = 1; // Enable global interrupts PORTC = 0x00; // Clear PORTC LATC = 0x00; // Clear PORTC latches TRISC = 0b00011000; // Set RC3, RC4 as inputs for I2C PORTB=0x00; LATB=0x00; TRISB=0x00; __delay_ms(100); do{ SSPCON2bits.SEN = 1; // set start bit SSPBUF=0x30; do{}while(!SSPIF); SSPIF=0; // SSPBUF=0x55; // do{}while(!SSPIF); // SSPIF=0; SSPCON2bits.PEN = 1; // set stop bit PORTBbits.RB5=1; __delay_ms(100); PORTBbits.RB5=0; __delay_ms(100);
}while(1); }
На RB5 - светодиод. Без строчек с SSP все мигает. При загрузке приведенного кода мигания нет. При запуске в отладке с PicKit3 происхдят "перескоки" на начало программы (даже если в теле программы про SSP только одна строчка старт-бита). Контроллер PIC16F1518, XC8 1.31, MPLAB-X 1.9, код слизан с AN734. Пните пожалуйста в нужном направлении.
|
|
|
|
|
May 29 2014, 07:30
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 5-05-14
Из: Минск
Пользователь №: 81 582

|
У вас разрешены прерывания, а где обработчик прерываний?
|
|
|
|
|
May 29 2014, 07:40
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 5-05-14
Из: Минск
Пользователь №: 81 582

|
Цитата(A. Fig Lee @ May 29 2014, 16:44)  А что, так можно: GIE = 1; //? и компайлер понимает? Я думал что только INTCONbits.GIE=1; Все биты прописаны через #define в заголовочном файле для контроллера. Вот пример для PIC24 Цитата /* INTCON2 */ #define _INT0EP INTCON2bits.INT0EP #define _INT1EP INTCON2bits.INT1EP #define _INT2EP INTCON2bits.INT2EP #define _DISI INTCON2bits.DISI #define _ALTIVT INTCON2bits.ALTIVT
|
|
|
|
|
May 29 2014, 08:46
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 29-01-08
Из: Нижний Новгород
Пользователь №: 34 535

|
Цитата(Voldemari4 @ May 29 2014, 15:40)  У вас разрешены прерывания, а где обработчик прерываний? добавил: Код void interrupt isr(void) { if (SSPIF) { Tmp=1; SSPIF=0; } if (BCLIF) { Tmp=1; BCLIF=0; } } и изменил: Код SPCON2bits.SEN = 1; // set start bit do{}while(SSPCON2bits.SEN); SSPBUF=0x30; do{}while(!Tmp); Tmp=0; SSPCON2bits.PEN = 1; // set stop bit Мыргает. На строке do{}while(SSPCON2bits.SEN) возникает BusCollision (вижу в режиме отладки PicKitом).  и на ногах SCL SDA ничего не происходит. Старта нет, посылки нет. Пинайте дальше.  Возможно что-то с конфигурацией не так, но она полностью слизана из апноута и на CCS старт и посылка адреса присутствовала.
|
|
|
|
|
May 29 2014, 08:58
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Цитата(animal @ May 29 2014, 08:56)  Мыргает. На строке do{}while(SSPCON2bits.SEN) возникает BusCollision (вижу в режиме отладки PicKitом).  и на ногах SCL SDA ничего не происходит. Старта нет, посылки нет. Пинайте дальше.  Возможно что-то с конфигурацией не так, но она полностью слизана из апноута и на CCS старт и посылка адреса присутствовала. Ну если бас коллижн, значит там уже "0" на той ноге. Я так понимаю. Резисторы подтяжки на + стоят? Че вольтметр показывает ДО старта?
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
May 30 2014, 01:32
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 29-01-08
Из: Нижний Новгород
Пользователь №: 34 535

|
Цитата(A. Fig Lee @ May 29 2014, 17:08)  Ну если бас коллижн, значит там уже "0" на той ноге. Я так понимаю. Резисторы подтяжки на + стоят? Че вольтметр показывает ДО старта? Резисторы подтяжки стоят на килооом на плюс. На выводах всегда +5. Не проскакивает ни импульса (следит осцил в режиме выборки). Далее код на CCS: Код #BYTE SSPCON1=0x0215 #BYTE SSPSTAT=0x0214 #BYTE SSPADD=0x0212 #BYTE SSPCON2=0x0216 #BYTE SSPCON3=0x0217 #BYTE SSPBUF=0x0211 #BYTE PIR1=0x0011 #BYTE PIE1=0x0091 #BYTE PIR2=0x0012 #BYTE PIE2=0x0092
#INT_SSP void ssp_interrupts() { Tmp_SSP=TRUE; clear_interrupt(INT_SSP); }
#INT_BUSCOL void ssp_collision() { Tmp_BUSCOL=TRUE; clear_interrupt(INT_BUSCOL); output_high(PIN_B5); }
void main() {setup_oscillator(OSC_16MHZ|OSC_INTRC); SSPCON1=0b00101000; //I2C master SSPCON3=0b00001000; SSPSTAT=0b10000000;//slew rate control disabled SSPADD=0x27; //100 kHz bit_set(PIE1,3);//SSPIE=1 interrupt enable bit_set(PIE2,3);//BCLIE=1 interrupt bus collision enable enable_interrupts(GLOBAL); delay_ms (500); do{ bit_set(SSPCON2,0); //start SEN=1 do{}while(bit_test(SSPCON2,0)); SSPBUF=0x08; do{}while(!Tmp_SSP); //SSPIF=? (interrupt=?) Tmp_SSP=0; SSPBUF=0x55; do{}while(Tmp_SSP); //SSPIF=? (interrupt=?) Tmp_SSP=0; bit_set(SSPCON2,2); //stop bit delay_us(100); }while(TRUE); }//main Код на CCS дает старт бит и посылку байта адреса, затем повтор. Нету у меня прав редактирования сообщений оказывается.  Запуск отладки на PickKit3 не показателен. Отладка на коде CCS тоже приводит к "перескоку" выполнения со строки do{}while(!Tmp_SSP); //после посылки адреса. Реально-же, байты адреса следуют друг за другом (без паузы в полсекунды). И, да, в программе на XC8, прерывания по BUSCOL на самом деле не происходит. Но на выводах все равно +5 и тишина...
|
|
|
|
|
May 30 2014, 02:20
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 5-05-14
Из: Минск
Пользователь №: 81 582

|
Ваша программа может зависать на циклах while. Все таки внутри цикла стоит сделать счетчик и выход через некоторое время в случае зависания. Попробуйте еще вместо ожидания флага прерывания после передачи поставить ожидание сброса бита SSPSTATbits.BF. И еще зачем вам прерывание void ssp_interrupts()?
|
|
|
|
|
May 30 2014, 02:31
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 29-01-08
Из: Нижний Новгород
Пользователь №: 34 535

|
Цитата(Voldemari4 @ May 30 2014, 10:30)  Ваша программа может зависать на циклах while. Все таки внутри цикла стоит сделать счетчик и выход через некоторое время в случае зависания. Попробуйте еще вместо ожидания флага прерывания после передачи поставить ожидание сброса бита SSPSTATbits.BF. И еще зачем вам прерывание void ssp_interrupts()? CCS-ный код приведен для примера, что MSSP контроллера признаки жизни подает и с пайкой ничего не напутано. Сконцентрировать внимание хотелось бы именно на XC8, так как планирую на него перейти. Проблема в том, что на XC8 MSSP признаки жизни вообще не подает. П.С.: Экспресс-опрос присутствующих. А на чем программируете Вы? И на чем, по вашему мнению, программирует большинство микрочиповцев?
|
|
|
|
|
May 30 2014, 07:10
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Я на XC8. Вот выжимка из рабочего кода PIC18F14K50: Код void Init() { SSPADD = 29; //48 MHz PLL, 12 MHz crystal SSPCON1bits.SSPM = 0x08; SSPCON1bits.SSPEN = 1;
// Enable priority interrupt RCONbits.IPEN = 1; INTCONbits.GIEL = 1; INTCONbits.GIEH = 1; IPR1bits.SSPIP = 0; PIE1bits.SSPIE = 1;
}
inline void I2C_wait() { while (PIR1bits.SSPIF == 0); }
uint8_t I2C_read(uint8_t addr) { uint8_t ret = 0xDD; //START SSPCON2bits.SEN = 1; I2C_wait(); //Device address SSPBUF = I2C_ADDR; I2C_wait(); //Device memory address SSPBUF = addr; I2C_wait();
//Repeated start SSPCON2bits.RSEN = 1; I2C_wait();
//Device address with READ bit on SSPBUF = I2C_ADDR | 0x01; I2C_wait();
//enable read SSPCON2bits.RCEN = 1; I2C_wait(); SSPCON2bits.ACKDT = 0; SSPCON2bits.ACKEN = 1; ret = SSPBUF; I2C_wait();
SSPCON2bits.RCEN = 1; I2C_wait(); SSPCON2bits.ACKDT = 0; SSPCON2bits.ACKEN = 1; ret = SSPBUF; I2C_wait();
SSPCON2bits.RCEN = 1; I2C_wait(); SSPCON2bits.ACKDT = 1; SSPCON2bits.ACKEN = 1; ret = SSPBUF; SSPCON2bits.PEN = 1; I2C_wait();
ret = SSPBUF; return ret; }
void interrupt low_priority LowPriorityInterrupt() { if (PIR1bits.SSPIF) { PIR1bits.SSPIF = 0; //i2c_interrupt(); } }
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
May 30 2014, 07:54
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 29-01-08
Из: Нижний Новгород
Пользователь №: 34 535

|
За выжимку спасибо. Я, хоть тресни, не вижу ошибки в коде. Модуль MSSP не подает вообще ни импульса. Конфигурацию проверил десять раз уже. Не могу понять где ошибка...
Сообщение отредактировал animal - May 30 2014, 07:55
|
|
|
|
|
May 30 2014, 08:32
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Цитата(animal @ May 30 2014, 08:04)  За выжимку спасибо. Я, хоть тресни, не вижу ошибки в коде. Модуль MSSP не подает вообще ни импульса. Конфигурацию проверил десять раз уже. Не могу понять где ошибка... Аналоговый блок есть там, отключен? А просто можками подергать/почитать - работает?
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
May 30 2014, 08:55
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 29-01-08
Из: Нижний Новгород
Пользователь №: 34 535

|
Цитата(A. Fig Lee @ May 30 2014, 16:42)  Аналоговый блок есть там, отключен? А просто можками подергать/почитать - работает? Добавил : ADCON0bits.ADON=0; //ADC disable Нет изменений. На CCS+MPLABX даже пытается I2С работать. Ноги точно рабочие.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|