Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Re: Програмирование pic на СИ.

Пт мар 22, 2019 20:08:02

всем добрый день, подскажите кто может, делаю проект в MPLAB IDE v8.92, имеются файлы main.c, SD_FAT.h, SD_FAT.c, SD_WAV.h SD_WAV.c, так вот, было бы очень здорово чтобы глобальные переменные объявленные в SD_FAT.c были видимы в SD_WAV.c, а вот как это замутить что то не знаю, есть ли возможность такового ?

Re: Програмирование pic на СИ.

Пт мар 22, 2019 20:31:16

Ключевое слово extern.

Re: Програмирование pic на СИ.

Пт мар 22, 2019 20:32:58

оказывается всё очень просто

Код:
В первой форме объявляется переменная
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

Re: Програмирование pic на СИ.

Ср авг 07, 2019 21:14:23

добрый день.
Уважаемые проблема примитивная и много всего в гугле нашёл по этой теме, но толку не какого, хочу подцепить PIC18F4550 по USB но, когда не понимаешь, что не работает толи с пиком толи с пк толи дрова корявые или проводок чего, разобраться не получается, что то толкового нет нечего, есть у кого нибудь исходники с прошивкой и терминалом, для этих дел, чтоб вот оп и заработало, ну а дальше яб разобрался.......

Re: Програмирование pic на СИ.

Чт авг 08, 2019 05:07:51

Здесь все есть:
https://www.microchip.com/mplab/microch ... mla-legacy
https://www.microchip.com/mplab/microch ... s/archives

Re: Програмирование pic на СИ.

Пт авг 16, 2019 10:26:11

Не стал создавать новую тему. Спрошу здесь.
Не могу побороть 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 сужу по сбою при инициализации дисплея, когда вместо чистого экрана получаю на нем мусор

Re: Програмирование pic на СИ.

Пт авг 16, 2019 19:28:20

давно не юзал Hi-Tech, скину рабочий код для XC думаю разберетесь
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 на СИ.

Пт авг 16, 2019 20:05:51

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 на СИ.

Пт авг 16, 2019 21:30:47

Обраьотка прерываний конечно же есть просто у меня она в другом файле находится
Код:
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 на СИ.

Пт авг 16, 2019 22:01:34

Хотел было уже написать, что код откомпилировался, но не заработал...
Но во-всяком случае в Протеус он работает. В железе смогу только в понедельник проверить.
Расскажу про мои вечерние приключениям по-порядку...
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 на СИ.

Пт авг 16, 2019 22:27:28

Этот код без изменений работает у меня на 18F4550
[img]
Изображение
[/img]

Добавлено after 5 minutes 1 second:
xc8 v2.05 который я использую собирает его без ругани, v2.09 дал целую кучу варнингов и 2 ошибки в разных файлах касающихся usb и ацп. v2.10 не пробывал

Добавлено after 5 minutes 1 second:
16F1825 у меня есть но я не делал отладочную плату для него

Re: Програмирование pic на СИ.

Сб авг 17, 2019 15:25:37

Специально глянул версию компилятора. У меня 2.05. Надо посмотреть, как обновляется.
Но дело, думаю, не в версии компилятора. Некоторые авторы специально не публикуют дополнительные хидеры и файлы. Но я вспомнил, где я видел этот код и обязательно загляну туда. Но я совсем не надеюсь получить там какие-либо пояснения. Поэтому далее надо самому разбираться.
Ну и по версии компилятора и типу микроконтроллера тут разницы не вижу. Код от Hi-Tech тоже прекрасно компилировался и работал в симуляторе. Но в реальном железе давал непонятный глюк. Так что надо и этот код проверять будет.

PS Обновил ХС8 до версии 2.10. Причем версия 2.05 тоже осталась установленной. Интересно, для чего?

Re: Програмирование pic на СИ.

Пн авг 19, 2019 09:17:28

XoXoJI, в общем не работает в железе у меня Ваш пример кода. Замучался уже. Я не применял указанный Вами драйвер дисплея, работал со своим. Ваш, во-первых, требует буфера, а у меня памяти под него нет. Во-вторых, считаю, не в нем дело. Вот либо я неправильно что-то в контроллере настроил в конфигурации, либо ошибка в другом. Кстати, инициализация дисплея в Вашем примере отличается по некоторым пунктам от рекомендуемой китайцами.
Изображение
Но опять же, с контроллерами AVR проблем с кодом не было.

Что сейчас происходит у меня. Информация начинает выводится на дисплей, но в какой-то момент вывод прекращается. И, при чем, всегда в разных местах

PS. при этом Proteus прожевывает любую инициализацию нормально, и в отличии от реального дисплея все достоверно выводит на дисплей

Re: Програмирование pic на СИ.

Пн авг 19, 2019 10:49:52

Я его спер с какогото сайта. Сейчас на работе, не могу проверить но инициализация эта вроде для дисплея 128х32 а не 128х64 как у маня и как у вас. Перенос строки по Y вроде неправильный. Приеду домой проверю.

Re: Програмирование pic на СИ.

Пн авг 19, 2019 11:01:53

но инициализация эта вроде для дисплея 128х32 а не 128х64 как у маня и как у вас. Перенос строки по Y вроде неправильный.

Кстати да! Я заметил, что вывод пошел через строчку , что характерно для 128х32. Так что это верно
Такое получается при
Код:
OLED_command(OLED_SETCOMPINS);         // 0xDA
OLED_command(0x02); // у китайцев 0х12

В общем вернул работу с драйвером Hi-Tech и вывод на дисплей заработал. Компилятор 2.10. Вот уж не знаю, в компиляторе ли дело или нет

Re: Програмирование pic на СИ.

Пн авг 19, 2019 11:09:02

Если информация выводится значит i2c работает. Надо ковырять драйвер ssd1306

Добавлено after 5 minutes 25 seconds:
Насколько я помню, для 128х64 после OLED_SETCOMPINS должно идти 0х12 а после OLED_SETMULTIPLEX 0x3F

Re: Програмирование pic на СИ.

Пн авг 19, 2019 11:34:59

Если информация выводится значит i2c работает. Надо ковырять драйвер ssd1306

Нет! Я поторопился с выводами. По-прежнему, если делать вывод одной и той же строчки в оду и ту же позицию с некоторым интервалом по времени, то происходит смещение отдельных символов на ±1 столбец. Для защиты своего драйвера ssd1306 скажу, что с AVR микроконтроллерами подобной проблемы нет, что с twi, что с usi версией интерфейса. Надо продолжать бороться с i2c драйвером.

Насколько я помню, для 128х64 после OLED_SETCOMPINS должно идти 0х12 а после OLED_SETMULTIPLEX 0x3F

Ну то же самое я привел с китайского даташита на дисплей

Re: Програмирование pic на СИ.

Пн авг 19, 2019 12:14:13

Дайте мне свой драйвер дисплея, приеду домой, закину в отладочную.

Re: Програмирование pic на СИ.

Пн авг 19, 2019 15:20:46

Отправил

Re: Програмирование pic на СИ.

Вт авг 20, 2019 11:06:55

XoXoJI, похоже заработал нормально Ваш драйвер для i2c.
Я долго искал причину, пока не вспомнил, что в драйвере от 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 В)...

И, похоже, что в этом то и состоял глюк. Если посмотреть модуль дисплея ssd1306, то у него питание подается через стабилизатор 3,3 В, при этом контроллер питается от 5 В. Но на сигнальных шинах уровень лог 1 равен 3,3 В, так как они подтянуты резисторами именно на уровень 3,3 В. Прав я или нет - не знаю, но по крайней мере код заработал нормально

Добавлено after 1 hour 1 minute 43 seconds:
С этим же значением регистра SSPSTAT Нормально заработал и драйвер от Hi-Tech, так как я изначально записывал туда значение 0x80, а не как в статье 0хС0
Ответить