Програмирование pic на СИ.
- БАТАРЕЙКУС
- Потрогал лапой паяльник
- Сообщения: 346
- Зарегистрирован: Сб фев 07, 2009 19:21:25
Re: Програмирование pic на СИ.
всем добрый день, подскажите кто может, делаю проект в MPLAB IDE v8.92, имеются файлы main.c, SD_FAT.h, SD_FAT.c, SD_WAV.h SD_WAV.c, так вот, было бы очень здорово чтобы глобальные переменные объявленные в SD_FAT.c были видимы в SD_WAV.c, а вот как это замутить что то не знаю, есть ли возможность такового ?
Мечтатель - не тот, кто сидит на диване и думает о несбыточном, а тот, кто всеми силами стремится воплотить несбыточное в реальность.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
Ключевое слово extern.
- БАТАРЕЙКУС
- Потрогал лапой паяльник
- Сообщения: 346
- Зарегистрирован: Сб фев 07, 2009 19:21:25
Re: Програмирование pic на СИ.
оказывается всё очень просто
взято отсюда http://www.cyberforum.ru/cpp-beginners/ ... 69502.html
Код: Выделить всё
В первой форме объявляется переменная
1 int q;
2 .......
3 // всякие действия с переменной
Во второй форме в коде пишем
1#include "Form1.h" //файл h первой формы, разумеется в общей папке должны лежать
2 extern int q; // получаем нашу переменную из первой формы
3 ...............
4 // продолжаем работу с переменной qвзято отсюда http://www.cyberforum.ru/cpp-beginners/ ... 69502.html
Мечтатель - не тот, кто сидит на диване и думает о несбыточном, а тот, кто всеми силами стремится воплотить несбыточное в реальность.
- БАТАРЕЙКУС
- Потрогал лапой паяльник
- Сообщения: 346
- Зарегистрирован: Сб фев 07, 2009 19:21:25
Re: Програмирование pic на СИ.
добрый день.
Уважаемые проблема примитивная и много всего в гугле нашёл по этой теме, но толку не какого, хочу подцепить PIC18F4550 по USB но, когда не понимаешь, что не работает толи с пиком толи с пк толи дрова корявые или проводок чего, разобраться не получается, что то толкового нет нечего, есть у кого нибудь исходники с прошивкой и терминалом, для этих дел, чтоб вот оп и заработало, ну а дальше яб разобрался.......
Уважаемые проблема примитивная и много всего в гугле нашёл по этой теме, но толку не какого, хочу подцепить PIC18F4550 по USB но, когда не понимаешь, что не работает толи с пиком толи с пк толи дрова корявые или проводок чего, разобраться не получается, что то толкового нет нечего, есть у кого нибудь исходники с прошивкой и терминалом, для этих дел, чтоб вот оп и заработало, ну а дальше яб разобрался.......
Мечтатель - не тот, кто сидит на диване и думает о несбыточном, а тот, кто всеми силами стремится воплотить несбыточное в реальность.
Re: Програмирование pic на СИ.
Не стал создавать новую тему. Спрошу здесь.
Не могу побороть mssp шину в режиме i2c master. Конкретно для подключения ssd1306.
Драйвер ssd1306 100% рабочий и нормально работает с контролерами AVR.
За основу я взял Hi-Tech C I2C Master Example Code http://www.hobbytronics.co.uk/hi-tech-c-i2c-master
Аналогичный код есть и тут https://electrosome.com/i2c-pic-microco ... mplab-xc8/
Разница лишь в регистре SSPSTAT.
Что меня сбивает по сравнению с шиной TWI в AVR, так это обилие всяких флагов и гораздо большее число регистров у PIC.
Код Hi-Tech рабочий, данные выводятся. Но со странным глюком. При выводе одной и той же информации в одну и ту же строчку, без предварительного затирания этой строчки, наблюдается эффект смещения на 1 столбец и появляется мусор. Строчка как бы дергается.
Грешу именно на код Hi-Tech, так как в сети для PICC и шины MSSP встречается очень большое число реализации кода. Я многое перепробовал и безуспешно. В слепую методом тыка я подбирать код не намерен, да и бессмысленно это.
Что смущает после шины TWI в AVR. Там вначале выставляются нужные биты в регистре, а затем следует задержка с проверкой флага прерывания TWINT.
В коде же Hi-Tech, наоборот, вначале идет проверка готовности, потом устанавливается бит, но нет проверки установки этого бита
Помогите с реализацией правильного драйвера i2c master
PS. Скопирую все же часть используемого мной кода Hi-Tech в данный момент, для упрощения. Кому надо подробнее, то ссылки указаны выше
PS2. Еще о неправильной работе драйвера i2c сужу по сбою при инициализации дисплея, когда вместо чистого экрана получаю на нем мусор
Не могу побороть mssp шину в режиме i2c master. Конкретно для подключения ssd1306.
Драйвер ssd1306 100% рабочий и нормально работает с контролерами AVR.
За основу я взял Hi-Tech C I2C Master Example Code http://www.hobbytronics.co.uk/hi-tech-c-i2c-master
Аналогичный код есть и тут https://electrosome.com/i2c-pic-microco ... mplab-xc8/
Разница лишь в регистре SSPSTAT.
Что меня сбивает по сравнению с шиной TWI в AVR, так это обилие всяких флагов и гораздо большее число регистров у PIC.
Код Hi-Tech рабочий, данные выводятся. Но со странным глюком. При выводе одной и той же информации в одну и ту же строчку, без предварительного затирания этой строчки, наблюдается эффект смещения на 1 столбец и появляется мусор. Строчка как бы дергается.
Грешу именно на код Hi-Tech, так как в сети для PICC и шины MSSP встречается очень большое число реализации кода. Я многое перепробовал и безуспешно. В слепую методом тыка я подбирать код не намерен, да и бессмысленно это.
Что смущает после шины TWI в AVR. Там вначале выставляются нужные биты в регистре, а затем следует задержка с проверкой флага прерывания TWINT.
В коде же Hi-Tech, наоборот, вначале идет проверка готовности, потом устанавливается бит, но нет проверки установки этого бита
Помогите с реализацией правильного драйвера i2c master
PS. Скопирую все же часть используемого мной кода Hi-Tech в данный момент, для упрощения. Кому надо подробнее, то ссылки указаны выше
Спойлер
Код: Выделить всё
// Initialise MSSP port.
void i2c_Init(void){
// Initialise I2C MSSP
// Master 100KHz
TRISA1=1; // set SCL and SDA pins as inputs
TRISA2=1;
SSPCON1 = 0b00101000; // I2C enabled, Master mode
SSPCON2 = 0x00;
// I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))
SSPADD = 19; // 100Khz @ 8Mhz Fosc
SSPSTAT = 0b11000000; // Slew rate disabled
}
// i2c_Wait - wait for I2C transfer to finish
void i2c_Wait(void){
while ( ( SSP1CON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
}
// i2c_Start - Start I2C communication
void i2c_Start(void)
{
i2c_Wait();
SEN=1;
}
// i2c_Restart - Re-Start I2C communication
void i2c_Restart(void){
i2c_Wait();
RSEN=1;
}
// i2c_Stop - Stop I2C communication
void i2c_Stop(void)
{
i2c_Wait();
PEN=1;
}
// i2c_Write - Sends one byte of data
void i2c_Write(unsigned char data)
{
i2c_Wait();
SSPBUF = data;
}PS2. Еще о неправильной работе драйвера i2c сужу по сбою при инициализации дисплея, когда вместо чистого экрана получаю на нем мусор
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
давно не юзал Hi-Tech, скину рабочий код для XC думаю разберетесь
i2c.h
i2c.c
ssd1306.h
Добавлено after 9 minutes 36 seconds:
ну и потом
i2c.h
Код: Выделить всё
#include<xc.h>
#define _XTAL_FREQ 20000000UL //Frequency of external oscillator in Hz
#define BUS_CLOCK_FREG 100000
void I2C_Init();
char I2C_Start();
void I2C_Ready();
char I2C_Write(unsigned char data);
char I2C_Stop();
char I2C_Read(char flag);
void I2C_Ack();
void I2C_Nack();
i2c.c
Код: Выделить всё
#include "i2c.h"
void I2C_Init()
{
TRISBbits.TRISB0 = 1;
TRISBbits.TRISB1 = 1;
SSPSTAT=0x80; /* Slew rate disabled, other bits are cleared */
SSPCON1=0x28; /* Enable SSP port for I2C Master mode,
clock = FOSC / (4 * (SSPADD+1))*/
SSPCON2=0x00;
SSPADD = (_XTAL_FREQ/(4*BUS_CLOCK_FREG))-1;
SSPIE=1; /* Enable SSPIF interrupt */
SSPIF=0;
GIE = 1;
PEIE = 1;
}
void I2C_Idle()
{
while(READ_WRITE);
ZERO=0;
while(ZERO)
{
SSPCON2&0x1f;
}
}
void I2C_IntWait(void)
{
while(!SSPIF);
SSPIF=0;
}
char I2C_Start()
{
SSPCON2bits.SEN=1; /* Send start pulse */
while(SSPCON2bits.SEN); /* Wait for completion of start pulse */
SSPIF=0;
if(!SSPSTATbits.S) /* Check whether START detected last */
return 0; /* Return 0 to indicate start failed */
}
void I2C_Ready()
{
while(BCLIF); /* Wait if bit collision interrupt flag is set*/
/* Wait for Buffer full and read write flag*/
while(SSPSTATbits.BF || (SSPSTATbits.R_nW));
SSPIF=0; /* Clear SSPIF interrupt flag*/
}
char I2C_Write(unsigned char data)
{
SSPBUF=data; /* Write data to SSPBUF*/
I2C_Ready();
if (ACKSTAT) /* Check for acknowledge bit*/
return 1;
else
return 2;
}
char I2C_Stop()
{
I2C_Ready();
PEN=1; /* Stop communication*/
while(PEN); /* Wait for end of stop pulse*/
SSPIF = 0;
if (!SSPSTATbits.P);/* Check whether STOP is detected last */
return 0;
}
char I2C_Read(char flag)
{
int buffer=0;
RCEN=1; /* Enable receive */
/* Wait for buffer full flag which when complete byte received */
while(!SSPSTATbits.BF);
buffer=SSPBUF; /* Copy SSPBUF to buffer */
/* Send acknowledgment or negative acknowledgment after read to
continue or stop reading */
if(flag==0)
I2C_Ack();
else
I2C_Nack();
I2C_Ready();
return(buffer);
}
void I2C_Ack()
{
ACKDT=0; /* Acknowledge data 1:NACK,0:ACK */
ACKEN=1; /* Enable ACK to send */
while(ACKEN);
}
void I2C_Nack()
{
ACKDT=1; /* Acknowledge data 1:NACK,0:ACK */
ACKEN=1; /* Enable ACK to send */
while(ACKEN);
}
ssd1306.h
Код: Выделить всё
#include <xc.h> // include processor files - each processor file is guarded.
#include "i2c.h"
#include <string.h>
#define OLED_SETCONTRAST 0x81
#define OLED_DISPLAYALLON_RESUME 0xA4
#define OLED_DISPLAYALLON 0xA5
#define OLED_NORMALDISPLAY 0xA6
#define OLED_INVERTDISPLAY 0xA7
#define OLED_DISPLAYOFF 0xAE
#define OLED_DISPLAYON 0xAF
#define OLED_SETDISPLAYOFFSET 0xD3
#define OLED_SETCOMPINS 0xDA
#define OLED_SETVCOMDETECT 0xDB
#define OLED_SETDISPLAYCLOCKDIV 0xD5
#define OLED_SETPRECHARGE 0xD9
#define OLED_SETMULTIPLEX 0xA8
#define OLED_SETLOWCOLUMN 0x00
#define OLED_SETHIGHCOLUMN 0x10
#define OLED_SETSTARTLINE 0x40
#define OLED_MEMORYMODE 0x20
#define OLED_COLUMNADDR 0x21
#define OLED_PAGEADDR 0x22
#define OLED_COMSCANINC 0xC0
#define OLED_COMSCANDEC 0xC8
#define OLED_SEGREMAP 0xA0
#define OLED_CHARGEPUMP 0x8D
static const unsigned char OLED_characters[] = {
0x00, 0x00, 0x00, 0x00, 0x00, // (Space)
0x00, 0x00, 0x5F, 0x00, 0x00, // !
0x00, 0x07, 0x00, 0x07, 0x00, // "
0x14, 0x7F, 0x14, 0x7F, 0x14, // #
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
0x23, 0x13, 0x08, 0x64, 0x62, // %
0x36, 0x49, 0x56, 0x20, 0x50, // &
0x00, 0x08, 0x07, 0x03, 0x00, // '
0x00, 0x1C, 0x22, 0x41, 0x00, // (
0x00, 0x41, 0x22, 0x1C, 0x00, // )
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // *
0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x00, 0x70, 0x30, 0x00, // ,
0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x00, 0x60, 0x60, 0x00, // .
0x20, 0x10, 0x08, 0x04, 0x02, // /
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x72, 0x49, 0x49, 0x49, 0x46, // 2
0x21, 0x41, 0x49, 0x4D, 0x33, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x3C, 0x4A, 0x49, 0x49, 0x31, // 6
0x41, 0x21, 0x11, 0x09, 0x07, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x46, 0x49, 0x49, 0x29, 0x1E, // 9
0x00, 0x00, 0x14, 0x00, 0x00, // :
0x00, 0x40, 0x34, 0x00, 0x00, // ;
0x00, 0x08, 0x14, 0x22, 0x41, // <
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x41, 0x22, 0x14, 0x08, // >
0x02, 0x01, 0x59, 0x09, 0x06, // ?
0x3E, 0x41, 0x5D, 0x59, 0x4E, // @
0x7C, 0x12, 0x11, 0x12, 0x7C, // A
0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x7F, 0x41, 0x41, 0x41, 0x3E, // D
0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x3E, 0x41, 0x41, 0x51, 0x73, // G
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x20, 0x40, 0x41, 0x3F, 0x01, // J
0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x7F, 0x02, 0x1C, 0x02, 0x7F, // M
0x7F, 0x04, 0x08, 0x10, 0x7F, // N
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
0x7F, 0x09, 0x19, 0x29, 0x46, // R
0x26, 0x49, 0x49, 0x49, 0x32, // S
0x03, 0x01, 0x7F, 0x01, 0x03, // T
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x3F, 0x40, 0x38, 0x40, 0x3F, // W
0x63, 0x14, 0x08, 0x14, 0x63, // X
0x03, 0x04, 0x78, 0x04, 0x03, // Y
0x61, 0x59, 0x49, 0x4D, 0x43, // Z
0x00, 0x7F, 0x41, 0x41, 0x41, // [
0x02, 0x04, 0x08, 0x10, 0x20, // "\"
0x00, 0x41, 0x41, 0x41, 0x7F, // ]
0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x03, 0x07, 0x08, 0x00, // `
0x20, 0x54, 0x54, 0x38, 0x40, // a
0x7F, 0x28, 0x44, 0x44, 0x38, // b
0x38, 0x44, 0x44, 0x44, 0x28, // c
0x38, 0x44, 0x44, 0x28, 0x7F, // d
0x38, 0x54, 0x54, 0x54, 0x18, // e
0x00, 0x08, 0x7E, 0x09, 0x02, // f
0x0C, 0x52, 0x52, 0x4A, 0x3C, // g
0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x20, 0x40, 0x40, 0x3D, 0x00, // j
0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x7C, 0x04, 0x78, 0x04, 0x78, // m
0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x38, 0x44, 0x44, 0x44, 0x38, // o
0x7C, 0x18, 0x24, 0x24, 0x18, // p
0x18, 0x24, 0x24, 0x18, 0x7C, // q
0x7C, 0x08, 0x04, 0x04, 0x08, // r
0x48, 0x54, 0x54, 0x54, 0x24, // s
0x04, 0x04, 0x3F, 0x44, 0x24, // t
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x44, 0x28, 0x10, 0x28, 0x44, // x
0x4C, 0x50, 0x50, 0x50, 0x3C, // y
0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x00, 0x08, 0x36, 0x41, 0x00, // {
0x00, 0x00, 0x77, 0x00, 0x00, // |
0x00, 0x41, 0x36, 0x08, 0x00, // }
0x02, 0x01, 0x02, 0x04, 0x02, // ~
};
static char OLED_buffer[512];
char address = 0x78;
void OLED_Init(char address1);
void OLED_command(char command);
void OLED_data(char data);
void OLED_write();
void OLED_clear();
void OLED_invert();
void OLED_rscroll(char start, char stop);
void OLED_lscroll(char start, char stop);
void OLED_stopscroll();
void OLED_pixel(short x, short y, char color);
void OLED_char(char character, short x, short y);
void OLED_string(char* str, short x, short y);
void OLED_Init(char address1) {
address = address1 << 1;
I2C_Init();
//__delay_ms(4);
OLED_command(OLED_DISPLAYOFF); // 0xAE
OLED_command(OLED_SETDISPLAYCLOCKDIV); // 0xD5
OLED_command(0x80); // the suggested ratio 0x80
OLED_command(OLED_SETMULTIPLEX); // 0xA8
OLED_command(0x1F);
OLED_command(OLED_SETDISPLAYOFFSET); // 0xD3
OLED_command(0x0); // no offset
OLED_command(OLED_SETSTARTLINE | 0x0); // line #0
OLED_command(OLED_CHARGEPUMP); // 0x8D
OLED_command(0xAF);
OLED_command(OLED_MEMORYMODE); // 0x20
OLED_command(0x00); // 0x0 act like ks0108
OLED_command(OLED_SEGREMAP | 0x1);
OLED_command(OLED_COMSCANDEC);
OLED_command(OLED_SETCOMPINS); // 0xDA
OLED_command(0x02);
OLED_command(OLED_SETCONTRAST); // 0x81
OLED_command(0xFF);
OLED_command(OLED_SETPRECHARGE); // 0xd9
OLED_command(0xF1);
OLED_command(OLED_SETVCOMDETECT); // 0xDB
OLED_command(0x40);
OLED_command(OLED_DISPLAYALLON_RESUME);// 0xA4
OLED_command(OLED_NORMALDISPLAY); // 0xA6
OLED_command(OLED_DISPLAYON); //--turn on oled panel
}
void OLED_command(char command) {
I2C_Start(); //StartI2C();
I2C_Write(address); //send address
I2C_Write(0x00); //send data incomming
I2C_Write(command); //send command
I2C_Stop(); //StopI2C();
}
void OLED_data( char data) {
I2C_Start(); //StartI2C();
I2C_Write(address); //send address
I2C_Write(0x40); //send data incomming
I2C_Write(data); //send data
I2C_Stop(); //StopI2C
}
void OLED_write(){
unsigned x;
OLED_command(OLED_COLUMNADDR) ;
OLED_command(0x00);
OLED_command(127);
OLED_command(OLED_PAGEADDR);
OLED_command(0x00);
OLED_command(3);
I2C_Start();
I2C_Write(address) ;
I2C_Write(0x40) ;
for(x = 0; x < 512; x++)
{
I2C_Write(OLED_buffer[x]);
}
I2C_Stop();
}
void OLED_clear(){
memset(OLED_buffer, 0x00, 512);
OLED_write();
}
void OLED_invert(){
OLED_command(OLED_INVERTDISPLAY);
}
void OLED_rscroll(char start, char stop) {
OLED_command(0x26);
OLED_command(0X00);
OLED_command(start);
OLED_command(0X00);
OLED_command(stop);
OLED_command(0X00);
OLED_command(0XFF);
OLED_command(0x2F); //Activate scroll
}
void OLED_lscroll(char start, char stop) {
OLED_command(0x27);
OLED_command(0X00);
OLED_command(start);
OLED_command(0X00);
OLED_command(stop);
OLED_command(0X00);
OLED_command(0XFF);
OLED_command(0x2F); //Activate scroll
}
void OLED_stopscroll() {
OLED_command(0x2E);
}
void OLED_pixel(short x, short y, char color){ //hmm, dosent include error checking..
char y_char = y%8;
short y_row = (y - y_char)*16 + x;
OLED_buffer[y_row] |= (color?1:0) << y_char;
}
void OLED_char(char character, short x, short y) {
short table_offset = (character-0x20)*5;
short offset = y*16 + x;
char i = 0;
for(; i < 5; i++) OLED_buffer[i+offset] = OLED_characters[i+table_offset];
}
void OLED_string(char* str, short x, short y) {
short pos = 0;
char character = str[pos++];
short startx = x;
short starty = y;
while(character != '\0') {
OLED_char(character, startx, starty);
if(startx >= 123) starty++; //wrap around
startx += 7;
character = str[pos++];
}
OLED_write();
}
Добавлено after 9 minutes 36 seconds:
ну и потом
Код: Выделить всё
OLED_Init(0x3C);
OLED_clear();
OLED_string("ssd1306 i2c 0x3c",0,0);
Re: Програмирование pic на СИ.
XoXoJI писал(а):скину рабочий код для XC
Спасибо за ответ! Я и использую компилятор ХС8, просто пример попался от компании Hi_Tech более понятный и осмысленный. Code Configurator даёт два варианта драйвера i2c. Один мощный, но избыточный. Он предполагает полную проверку и контроль над шиной i2c, но при этом требует буфера для передачи данных. Памяти в той же ATmega8 на буфер нет. А применять ATmega328 избыточно для проекта. Второй драйвер даёт лишь базовый контроль и там надо самому собирать код работы с шиной. Я с ним так и не разобрался.
Подобный код, что Вы привели в примере, я 100% встречал в сети. Запомнился очень по:
Код: Выделить всё
void I2C_Idle()
{
while(READ_WRITE);
ZERO=0;
while(ZERO)
{
SSPCON2&0x1f;
}
}При том, что ZERO нигде не объявлена и зачем ее еще в цикл помещать? Я не программист и вот таких шаманских пассов не понимаю.
И чем данный кусок кода отличается от приведенного в примере?
Код: Выделить всё
// i2c_Wait - wait for I2C transfer to finish
void i2c_Wait(void){
while ( ( SSP1CON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
}Далее, смущает инициализация прерывания
Код: Выделить всё
SSPIE=1;при отсутствии самого обработчика прерывания. В AVR GCС было обязательным создание обработчика в коде, даже если он пустой.
В общем код ради интереса попробую. Чем черт не шутит. Но пока вижу очень схожий по смыслу код, только с проверкой бОльшего числа флагов, чем в примере Hi-Tech
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
Обраьотка прерываний конечно же есть просто у меня она в другом файле находится
я уже и не помню откуда этот код у меня, очень много времени прошло. Он рабочий 100%
Добавлено after 9 minutes 37 seconds:
Ни в одном хидере включенном в xc.h мне не удалось найти ZERO и READ_WRITE, но компилятор хавает их без ругани. Может найдется человек, который сможет пояснить что это такое. У меня весь стаж под windows для пиков пишу года 1,5 только.
Код: Выделить всё
void interrupt SYS_InterruptHigh(void)
{
if(SSPIF)
{
SSPIF = 0;
}
}
я уже и не помню откуда этот код у меня, очень много времени прошло. Он рабочий 100%
Добавлено after 9 minutes 37 seconds:
Ни в одном хидере включенном в xc.h мне не удалось найти ZERO и READ_WRITE, но компилятор хавает их без ругани. Может найдется человек, который сможет пояснить что это такое. У меня весь стаж под windows для пиков пишу года 1,5 только.
Re: Програмирование pic на СИ.
Хотел было уже написать, что код откомпилировался, но не заработал...
Но во-всяком случае в Протеус он работает. В железе смогу только в понедельник проверить.
Расскажу про мои вечерние приключениям по-порядку...
У меня без ругани скушал только ZERO но так как я не нашел её(переменной) ни в одном из хидеров, то тупо присвоил ей тип переменной. Стало так
Что касается READ_WRITE, то пришлось объявить макросом, иначе компилятор матерился
После этих изменений код прошел компиляцию, выдав по дороге три варнинга на функции Start, Stop и Write, так как они возвращают значение, а в коде это не используется. Но в симуляторе не заработал.
Ситуацию сдвинуло с мертвой точки последнее сообщение. После указания вектора прерывания все заработало. Но! Повторюсь. Надо проверить в железе.
Надо поискать в сети, откуда у этого кода растут ноги и разобраться с функциями Start, Stop и Write.
Ну и напоследок, код
тоже работает.
PS. SSP1IF - это не ошибка. Я использую в качестве подопытного контроллер PIC16F1825 и в регистрах mssp присутствует в названии 1
Но во-всяком случае в Протеус он работает. В железе смогу только в понедельник проверить.
Расскажу про мои вечерние приключениям по-порядку...
serg_svd писал(а):но компилятор хавает их без ругани
У меня без ругани скушал только ZERO но так как я не нашел её(переменной) ни в одном из хидеров, то тупо присвоил ей тип переменной. Стало так
Код: Выделить всё
void I2C_Idle(void)
{
while(READ_WRITE);
uint8_t ZERO=0;
while(ZERO)
{
(SSP1CON2 & 0x1f);
}
}Что касается READ_WRITE, то пришлось объявить макросом, иначе компилятор матерился
Код: Выделить всё
#define READ_WRITE (SSP1STAT & 0x04)После этих изменений код прошел компиляцию, выдав по дороге три варнинга на функции Start, Stop и Write, так как они возвращают значение, а в коде это не используется. Но в симуляторе не заработал.
Ситуацию сдвинуло с мертвой точки последнее сообщение. После указания вектора прерывания все заработало. Но! Повторюсь. Надо проверить в железе.
Код: Выделить всё
void __interrupt() mssp_Interrupt(void)
{
if(SSP1IF)
{
SSP1IF=0;
}
}Надо поискать в сети, откуда у этого кода растут ноги и разобраться с функциями Start, Stop и Write.
Ну и напоследок, код
Код: Выделить всё
// i2c_Wait - wait for I2C transfer to finish
void i2c_Wait(void){
while ( ( SSP1CON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
}тоже работает.
PS. SSP1IF - это не ошибка. Я использую в качестве подопытного контроллер PIC16F1825 и в регистрах mssp присутствует в названии 1
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
Этот код без изменений работает у меня на 18F4550
[img]

[/img]
Добавлено after 5 minutes 1 second:
xc8 v2.05 который я использую собирает его без ругани, v2.09 дал целую кучу варнингов и 2 ошибки в разных файлах касающихся usb и ацп. v2.10 не пробывал
Добавлено after 5 minutes 1 second:
16F1825 у меня есть но я не делал отладочную плату для него
[img]
[/img]
Добавлено after 5 minutes 1 second:
xc8 v2.05 который я использую собирает его без ругани, v2.09 дал целую кучу варнингов и 2 ошибки в разных файлах касающихся usb и ацп. v2.10 не пробывал
Добавлено after 5 minutes 1 second:
16F1825 у меня есть но я не делал отладочную плату для него
Re: Програмирование pic на СИ.
Специально глянул версию компилятора. У меня 2.05. Надо посмотреть, как обновляется.
Но дело, думаю, не в версии компилятора. Некоторые авторы специально не публикуют дополнительные хидеры и файлы. Но я вспомнил, где я видел этот код и обязательно загляну туда. Но я совсем не надеюсь получить там какие-либо пояснения. Поэтому далее надо самому разбираться.
Ну и по версии компилятора и типу микроконтроллера тут разницы не вижу. Код от Hi-Tech тоже прекрасно компилировался и работал в симуляторе. Но в реальном железе давал непонятный глюк. Так что надо и этот код проверять будет.
PS Обновил ХС8 до версии 2.10. Причем версия 2.05 тоже осталась установленной. Интересно, для чего?
Но дело, думаю, не в версии компилятора. Некоторые авторы специально не публикуют дополнительные хидеры и файлы. Но я вспомнил, где я видел этот код и обязательно загляну туда. Но я совсем не надеюсь получить там какие-либо пояснения. Поэтому далее надо самому разбираться.
Ну и по версии компилятора и типу микроконтроллера тут разницы не вижу. Код от Hi-Tech тоже прекрасно компилировался и работал в симуляторе. Но в реальном железе давал непонятный глюк. Так что надо и этот код проверять будет.
PS Обновил ХС8 до версии 2.10. Причем версия 2.05 тоже осталась установленной. Интересно, для чего?
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
XoXoJI, в общем не работает в железе у меня Ваш пример кода. Замучался уже. Я не применял указанный Вами драйвер дисплея, работал со своим. Ваш, во-первых, требует буфера, а у меня памяти под него нет. Во-вторых, считаю, не в нем дело. Вот либо я неправильно что-то в контроллере настроил в конфигурации, либо ошибка в другом. Кстати, инициализация дисплея в Вашем примере отличается по некоторым пунктам от рекомендуемой китайцами.

Но опять же, с контроллерами AVR проблем с кодом не было.
Что сейчас происходит у меня. Информация начинает выводится на дисплей, но в какой-то момент вывод прекращается. И, при чем, всегда в разных местах
PS. при этом Proteus прожевывает любую инициализацию нормально, и в отличии от реального дисплея все достоверно выводит на дисплей
Но опять же, с контроллерами AVR проблем с кодом не было.
Что сейчас происходит у меня. Информация начинает выводится на дисплей, но в какой-то момент вывод прекращается. И, при чем, всегда в разных местах
PS. при этом Proteus прожевывает любую инициализацию нормально, и в отличии от реального дисплея все достоверно выводит на дисплей
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
Я его спер с какогото сайта. Сейчас на работе, не могу проверить но инициализация эта вроде для дисплея 128х32 а не 128х64 как у маня и как у вас. Перенос строки по Y вроде неправильный. Приеду домой проверю.
Re: Програмирование pic на СИ.
[uquote="XoXoJI",url="/forum/viewtopic.php?p=3685412#p3685412"]но инициализация эта вроде для дисплея 128х32 а не 128х64 как у маня и как у вас. Перенос строки по Y вроде неправильный.[/uquote]
Кстати да! Я заметил, что вывод пошел через строчку , что характерно для 128х32. Так что это верно
Такое получается при
В общем вернул работу с драйвером Hi-Tech и вывод на дисплей заработал. Компилятор 2.10. Вот уж не знаю, в компиляторе ли дело или нет
Кстати да! Я заметил, что вывод пошел через строчку , что характерно для 128х32. Так что это верно
Такое получается при
Код: Выделить всё
OLED_command(OLED_SETCOMPINS); // 0xDA
OLED_command(0x02); // у китайцев 0х12В общем вернул работу с драйвером Hi-Tech и вывод на дисплей заработал. Компилятор 2.10. Вот уж не знаю, в компиляторе ли дело или нет
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
Если информация выводится значит i2c работает. Надо ковырять драйвер ssd1306
Добавлено after 5 minutes 25 seconds:
Насколько я помню, для 128х64 после OLED_SETCOMPINS должно идти 0х12 а после OLED_SETMULTIPLEX 0x3F
Добавлено after 5 minutes 25 seconds:
Насколько я помню, для 128х64 после OLED_SETCOMPINS должно идти 0х12 а после OLED_SETMULTIPLEX 0x3F
Re: Програмирование pic на СИ.
[uquote="XoXoJI",url="/forum/viewtopic.php?p=3685416#p3685416"]Если информация выводится значит i2c работает. Надо ковырять драйвер ssd1306[/uquote]
Нет! Я поторопился с выводами. По-прежнему, если делать вывод одной и той же строчки в оду и ту же позицию с некоторым интервалом по времени, то происходит смещение отдельных символов на ±1 столбец. Для защиты своего драйвера ssd1306 скажу, что с AVR микроконтроллерами подобной проблемы нет, что с twi, что с usi версией интерфейса. Надо продолжать бороться с i2c драйвером.
[uquote="XoXoJI",url="/forum/viewtopic.php?p=3685416#p3685416"]Насколько я помню, для 128х64 после OLED_SETCOMPINS должно идти 0х12 а после OLED_SETMULTIPLEX 0x3F[/uquote]
Ну то же самое я привел с китайского даташита на дисплей
Нет! Я поторопился с выводами. По-прежнему, если делать вывод одной и той же строчки в оду и ту же позицию с некоторым интервалом по времени, то происходит смещение отдельных символов на ±1 столбец. Для защиты своего драйвера ssd1306 скажу, что с AVR микроконтроллерами подобной проблемы нет, что с twi, что с usi версией интерфейса. Надо продолжать бороться с i2c драйвером.
[uquote="XoXoJI",url="/forum/viewtopic.php?p=3685416#p3685416"]Насколько я помню, для 128х64 после OLED_SETCOMPINS должно идти 0х12 а после OLED_SETMULTIPLEX 0x3F[/uquote]
Ну то же самое я привел с китайского даташита на дисплей
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
Дайте мне свой драйвер дисплея, приеду домой, закину в отладочную.
Re: Програмирование pic на СИ.
Отправил
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Re: Програмирование pic на СИ.
XoXoJI, похоже заработал нормально Ваш драйвер для i2c.
Я долго искал причину, пока не вспомнил, что в драйвере от Hi-Tech при инициализации регистр SSPSTAT устанавливалось значение не 0х80, а
Полез в даташит. В моем вольном переводе значится:
Полез в инет искать описание протокола SMBus и вот, что обнаружил в Вики:
Добавлено after 1 hour 1 minute 43 seconds:
С этим же значением регистра SSPSTAT Нормально заработал и драйвер от Hi-Tech, так как я изначально записывал туда значение 0x80, а не как в статье 0хС0
Я долго искал причину, пока не вспомнил, что в драйвере от Hi-Tech при инициализации регистр SSPSTAT устанавливалось значение не 0х80, а
Код: Выделить всё
SSPSTAT = 0b11000000; // Slew rate disabledПолез в даташит. В моем вольном переводе значится:
Код: Выделить всё
CKE (SPI Clock Select bit) — Выбор фронта передачи сигнала
Ведущий или ведомый режим I2C:
1 — Входные данные соответствуют спецификации SMBus
0 — Входные данные не соответствуют спецификации SMBus (соответствуют спецификации I2C).Полез в инет искать описание протокола SMBus и вот, что обнаружил в Вики:
- SMBus (англ. System Management Bus) — последовательный протокол обмена данными для устройств питания. Основан на шине I²C, но использует более низкое сигнальное напряжение (3,3 В)...
Добавлено after 1 hour 1 minute 43 seconds:
С этим же значением регистра SSPSTAT Нормально заработал и драйвер от Hi-Tech, так как я изначально записывал туда значение 0x80, а не как в статье 0хС0
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.