Перейти к содержанию

Подскажите пример настройки и работы с UART PIC18F25K80


Ostroukhovio

Рекомендуемые сообщения

Народ подскажите пожалуйста примерчик настройки и работы с приемником контроллера UART1. Нужно со считывателя карт доступа CP-Z-2  по протоколу 1990а получать массив байт. Уже всю голову сломал, либо не получаю ничего, либо все байты 255.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

С этими считывателями уже работали на АВР просто. А  UART потому-что он просто напросто уже применен при разводке платы. Используем провод считывателя на входе RX (ножка RC7) контроллера. Да и таблеток под рукой нет, только CP-Z и ключ-карточка доступа. 

Сам по себе юарт настроился так как при прикладывании карточки к считывателю я явно вижу уход в прерывание по светодиоду сервисному и звукоизлучателю на моей плате, проблема именно как на этом PIC правильно организовать обработку 12 последовательных байт ID ключа. 

Изменено пользователем Ostroukhovio
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Модуль UART для этой цели не подойдет, протоколы разные. Надо программировать 1 Wire, я в свое время делал замки на базе PIC18, если надо - могу поделиться.

Ссылка на комментарий
Поделиться на другие сайты

На AVR именно на приемнике UART и катаем считыватели. Хочу пересадить изделие на свой родной PIC, но какаято ерунда: считыватель должен на протоколе 1990а отдать стартовый байт, 6 байт ключа и проверочный байт, но по факту при крикладывании карты я получаю всего один байт, то есть прерывание срабатывает всего один раз. Проверка байт осуществляется по штатному ряду светодиодов WS2812, загорается всего один вместо 8 или 12 шт. 

6 часов назад, Станислав сказал:

Модуль UART для этой цели не подойдет, протоколы разные. Надо программировать 1 Wire, я в свое время делал замки на базе PIC18, если надо - могу поделиться.

Для общего развития был бы рад изучить такой вариант

Ссылка на комментарий
Поделиться на другие сайты

Я так понимаю, если делать 1 wire на своей функции обработки, учитывая что считыватель в отличае от прочих микросхем никого не спрашивая сразу выплевывает ID карточки, нужно вылавливать в цикле while первое изменение состояние на ножке МК и далее по таймингам прям писать в массив биты формируя байты? 

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Ostroukhovio сказал:

///////////////

Ты на асме будешь мучатся? Да ещё зверя взяли PIC18F25K80...

Лет с 8 назад делал что-то типа контроль доступа ...  Связка МК память релюхи, светодиоды и часики... и 485 с сервером...

Начни с простого, последовательно...

Инициализируй ВСЕ порты ( 1варе, уарт, светодиоды, релюхи... и незадействованые в хай зет вгони).

init_gpio_ports();

init_что_то_там();

Init_interrupt();

Потом

init_1ware();

init_uart(); // для отладки самое то

//Выдай на терминал, что у тя все стартануло 

serial_out("-start-\r\n");

Если дойдет до этого этапа, помогу дальше..

Ссылка на комментарий
Поделиться на другие сайты

4 часа назад, Ostroukhovio сказал:

нужно вылавливать в цикле while первое изменение состояние на ножке МК и далее по таймингам прям писать в массив биты формируя байты? 

читая этот поток бессознательного возникает полная уверенность, что никакого 

7 часов назад, Ostroukhovio сказал:

На AVR именно на приемнике UART и катаем считыватели.

не было... либо вы в нем не участвовали иначе знали бы , шта принцип работы ЮАРТа в качестве ван_варе одинаков для любых контроллеров хоть для ПЫКов хоть для АВР, хоть для СТМ , и описан в апнопе 214 от максимки APP214 "Using a UART to Implement a 1-Wire Bus Master" 
если кратко все сводится к

Цитата

Reset выполняется так — настройки порта 9600,8,n,1, отправляем 0xf0, если приходит не 0xf0 – значит на линии кто-то сидит.
Для всех остальных действий настройки порта 115200,8,n,1
Запись 0 — отправляем 0х00. По идее и прийти должно 0x00
Запись 1 — отправляем 0хff. По идее и прийти должно 0xff
Чтение — отправляем 0xff. Если вернулось 0xff – прочиталась 1, иначе — 0.
для записать/прочитать байт на линию 1-wire, нам надо прокачать 8 байт через USART

:big_boss::spiteful:
 

Ссылка на комментарий
Поделиться на другие сайты

6 часов назад, Azazelius сказал:

/////////

До этого изделие работало на 328 меге, данный PIC применили так как требуется CAN. Отладку ловлю в данный момент именно с CAN-USB переходника. 

4 часа назад, IMXO сказал:

////////

То что UART работает везде идентично это и ежу понятно, по этому и непонятки, где мои данные) 

Ссылка на комментарий
Поделиться на другие сайты

#define F_CPU 40000000

int RF_ID[16];

void main(void){
    SYSTEM_Initialize();
    UART_Config(9600);
    IO_Config(1);
    
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    
    while(1){
        if(PIE1bits.RC1IE == 1 && PIR1bits.RC1IF == 1){
            int i;
            for(i = 0; i < 8; i++){   
                RF_ID[i] = USART_RxChar();
            } 
        }
    }
}

void IO_Config(char Mode){
    TRISA = 0;
    TRISB = 0;
    TRISC = 0;
    
    //Отключение АЦП
    PCFG0 = 0;
    PCFG1 = 0;
    PCFG2 = 0;
    PCFG3 = 0;
    VNCFG = 0;
    ADCON1 = 0x0;//0x07;

    /*Светодиоды*/
    kLED_tris = 0;
    kLED_lat = 0;

    /*Звук*/
    kSOUND_tris = 0;
    kSOUND_lat = 0;
    
    /*Замок*/
    kLOCK_tris = 0;
    kLOCK_lat = 0;
    
    /*Защитный датчик*/
    iGUARD_tris = 1;
    iGUARD_lat = 0;
    
    /*RFID*/
    iRFID_tris = 1;
    iRFID_lat = 0;
    
     /*Геркон*/
    iGER_tris = 1;
    iGER_lat = 0;
    
    /*Сброс Ethernet (инверсно)*/
    kETHRES_tris = 0;
    kETHRES_lat = 0;
}
                             
void UART_Config(long baud_rate){
    float bps; 
    bps = (( (float) (F_CPU) / (64 * (float) baud_rate)) - 1);
    SPBRG1 = (int)bps;
    TXSTA1bits.CSRC = 0;
    TXSTA1bits.TX9 = 0;
    TXSTA1bits.TXEN = 0;
    TXSTA1bits.SYNC = 0;
    TXSTA1bits.BRGH = 0;
    BAUDCON1bits.BRG16 = 0;
    RCSTA1 = 0x90;
    PIR1bits.RCIF = 0;
    PIE1bits.RCIE = 1;
}

int USART_RxChar(void){
    while(PIR1bits.RC1IF == 0);
    NOP();
    if(RCSTAbits.OERR){           
        RCSTAbits.CREN = 0;
        NOP();
        RCSTAbits.CREN = 1;
    }
    int DATA;
    DATA = RCREG1;
    PIR1bits.RC1IF = 0;
    return DATA;
}

Выдержки из моего тестового кода.

Изменено пользователем Ostroukhovio
Ссылка на комментарий
Поделиться на другие сайты

небольшой ликбез:
в среднем семействе ПИКов нет отдельных адресов прерываний,
в ПИК18 векторов прерывания всего два : высший по адресу 0008h и низший по 0018h(по дефолту включен только высший приоритет RCON.IPEN=0)
прерывания делятся на основные и периферийные , ЮАРТ относится к периферийным
для разрешения прерываний от него при отключенном приоритете , должны быть разрешено глобальное прерывание GIE , прерывание от периферии  PEIE  а так же  передатчик и приемник ЮАРТ TX1IE, RC1IE.
флаги прерывания выставляются автоматически вне зависимости включены прерывания или нет , автоматического сброса флагов в прерывании как в АВР нет, флаги сбрасываются только программно, если в разрешенном прерывании флаг не будет сброшен прога из прерывания не выйдет.

ЗЫ конструкция вида

  if(PIE1bits.RC1IE == 1 && PIR1bits.RC1IF == 1){
            // что-то там.....
            PIR1bits.RC1IF == 0;
            } 
        

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

ЗЫЫ для настройки ЮАРТ лучше использовать режим 16ти битной константы и формулу  X = ((FOSC/Desired Baud Rate)/4) – 1 , с ней самая минимальная погрешность при настройке частоты ЮАРТ.


 

Ссылка на комментарий
Поделиться на другие сайты

Все разрешилось, считыватель ждал от меня ответа перед началом трансляции ID:

RFID.h

#ifndef RFID_H
#define	RFID_H

#include <xc.h>

#define RFID_tris                   TRISC7
#define RFID_port                   RC7
#define RFID_lat                    LATC7

#define _XTAL_FREQ 40000000

unsigned char RFID_id[8];
char RFID_ready;

void RFID_config(void);
char RFID_reset(void);
void RFID_write(unsigned char Byte, char Power);
void RFID_write_bit(char Bit);
unsigned char RFID_read(void);
char RFID_read_bit(void);
void RFID_scan(char Power); 

#endif	/* RFID_H */

RFID.c

#include "RFID.h"

void Interrupts(char Mode){
    INTCONbits.GIE = Mode;
    INTCONbits.PEIE = Mode;
}

void RFID_config(void){
    RFID_lat = 0;
	RFID_tris = 1;
    RFID_ready = 0;
}

char RFID_reset(void){
	char Response;
	char Retries = 125;

	Interrupts(0);
    RFID_lat = 0;
	RFID_tris = 1;
	Interrupts(1);
	// wait until the wire is high... just in case
	do{
		if(--Retries == 0) return 0;
		__delay_us(2);
	}while(!RFID_port);

	Interrupts(0);
	RFID_lat = 0;
	RFID_tris = 0;
	Interrupts(1);
	__delay_us(480);
    
	Interrupts(0);
	RFID_tris = 1;
	__delay_us(70);
	Response = !RFID_port;
	Interrupts(1);
	__delay_us(410);
	return Response;
}

void RFID_write(unsigned char Byte, char Power){
    unsigned char bitMask;

    for(bitMask = 0x01; bitMask; bitMask <<= 1){
        RFID_write_bit((bitMask & Byte)?1:0);
    }
    if (!Power) {
        Interrupts(0);
        RFID_tris = 1;
        RFID_lat = 0;
        Interrupts(1);
    }
}

void RFID_write_bit(char Bit){
    Interrupts(0);
    RFID_lat = 0;
    RFID_tris = 0;
	if(Bit){
		__delay_us(10);
		RFID_lat = 1;
		Interrupts(1);
		__delay_us(55);
	} else {
		__delay_us(65);
		RFID_lat = 1;
		Interrupts(1);
		__delay_us(5);
	}
}

unsigned char RFID_read(void){
    unsigned char bitMask;
    unsigned char Byte = 0;

    for (bitMask = 0x01; bitMask; bitMask <<= 1){
        if(RFID_read_bit()) Byte |= bitMask;
    }
    return Byte;
}

char RFID_read_bit(void){
	char Bit;

	Interrupts(0);
    RFID_tris = 0;
	RFID_lat = 0;
	__delay_us(3);
	RFID_tris = 1;
	__delay_us(10);
	Bit = RFID_port;
	Interrupts(1);
	__delay_us(53);
    LATA3 = Bit;
	return Bit;
}

void RFID_scan(char Power){ 
    if(RFID_reset()){ // Если карта приложена
        RFID_ready = 0;
        RFID_write(0x33, Power); // вернуть ридеру команду на чтение байт
        int i;
        for(i = 0; i < 8; i++) {
           RFID_id[i] = RFID_read(); // здесь искомые стартовый байт, 6 байт данных и crc
        }
        RFID_ready = 1;
    } 
}

Main.c

//Предварительная конфигурация
RFID_config();
 
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;

//Полученный от считывателя ID-карты ключа записывается в массив RFID_id[8].
//RFID_ready - флаг устанавливаемый моей библиотекой при прочтении очередного ID ключа-карты.
//После обработки полученного ID карты-ключа, необходимо сбросить данный флаг иначе библиотека не продолжит работу со считывателем.
while(1){
    if(!RFID_ready) RFID_scan(0);
}

Всем спасибо и удачи!

Изменено пользователем Ostroukhovio
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...