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

Язык СИ для микроконтроллеров


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

Действительно есть такое,буду повнимательней.

Только не пойму как эта функция работает,смотрел примеры из папки Other --> sprintf,sprinti,sprintl.Вот не выводят же они данные в через uart , а делает это UART1_Write_Text.Не пойму чем sprintf и ему подобные аналоги printf ?

Искал ключик к mikroC Pro Pic 4.60.0.0 так и не нашол,может у кого есть кинет на мыло Penchev@yandex.ru.Спасибо.

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

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

Совет на будущие:

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

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

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

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

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

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

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

Я еще не совсем понимаю работу с библиотеками,вот пример работы с функцией sprinti.Можете объяснить как все происходит.

Подключены библиотеки sprinti,uart,C_Type.

Результатом работы программы является текст в терменале Proteus:

Integer number representation

в format: 30000

x format: 7530

unsigned int int_no = 30000;

char buffer[15];

void main(){

UART1_Init(9600); // Initialize UART module at 9600 bps

Delay_ms(10);

UART1_Write_Text("Integer number representation"); // Write message on UART

sprinti(buffer, "%10d", int_no); // Format int_no and store it to buffer

UART1_Write_Text("\r\nd format:"); // Write message on UART

UART1_Write_Text(buffer); // Write buffer on UART (decimal format)

sprinti(buffer, "%10x", int_no); // Format int_no and store it to buffer

UART1_Write_Text("\r\nx format:"); // Write message on UART

UART1_Write_Text(buffer); // Write buffer on UART (hex format)

}

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

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

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

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

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

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

Вы совершенно правы вопрос мутный получился.

Вот функция к примеру printf что делает мне понятно и привычно видеть вывод текста в uart как в CCS-PICC, например так printf ("Hallo world");

Но в mikroC вывод даных происходит функцией UART1_Write_Text("Hallo world");

А sprintf,sprinti и sprintl что за звери и для чего?

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

>>А sprintf,sprinti и sprintl что за звери и для чего?

Эти функции отправляют/принимают данные со стандартного устройства ввода/вывода. Что подразумевается под стандартным вводом/ выводом нужно читать в документации для каждого конкретного случая. Например есть компиляторы в которых эти функции не имеют реализации (стоят заглушки) в таких системах программист сам определяет куда отправлять данные.

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

Наверное с microC буду завязывать,мне кажится он немного ушол от стандарта языка си.

На данный момент стоит CCS-PICC,есть ли отличие от HI-TECH,какой для начинающего Вы бы посоветовали?

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

Тут я Вам не советчик. Я PIC только на картинках видел.

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

Я вот почитал Ваши измышления и никак не пойму, зачем Вам для программирования МК такие функции как scanf и printf, что Вы с ними делать то собираетесь ? Есть у микроСи свои библиотеки для вывода в UART чем они Вам не угодили ? Ни один компиль для МК не работает полностью по стандартам Си т.к у МК есть определённые ограничения. А если так уж нужен "стандарт" то берёте и делаете вывод с помощью ассемблерной вставки по примерам микрочипа. К тому же в хелпе на микроСи есть раздел, который так и называется особенности и ограничения компилятора микроСи. Если Вы не хотите использовать готовые библиотеки микроСи, пишите свои, Вам это никто не запрещает.

К Вашей проблеме по поводу printf, вот что сказано в мануале :

MikroC предоставляет библиотеку функций вывода sprint.

Примечание: В дополнение к стандарту ANSI Си mikroC предоставляет ограниченные версии sprinti, sprintl, которые занимают меньше ROM, RAM и могут быть удобны в некоторых случаях для PIC.

Ползуйтесь sprintf тоже самое, что и printf.

Про ограничения: Местами mikroC отличается от ANSI Cи. Некоторые из этих отличий являются улучшениями, способствующими облегчению программирования для PIC, тогда как другие являются следствиями аппаратных ограничений, присущих PICmicro

Будьте проще и люди к вам потянутся.

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

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

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

  • 1 месяц спустя...
  • 3 недели спустя...

Здравствуйте, помогите наити ошибку в программе

	# include <pic.h>	// PIC16F877A
# include "delay.h"
__CONFIG ( XT & WDTDIS & PWRTEN & BOREN & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT ) ;
# define 		_XTAL_FREQ 4000000  // Определить частоту МК
# define 		bitset(var, bitno) ((var) |= 1UL << (bitno))
# define 		bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
// ОПРЕДЕЛИТЬ ПИНЫ
# define 	DQ		RA2
# define  port_catod PORTB
// ПРОТОТИПЫ

// ПЕРЕМЕННЫЕ
unsigned char dig[4];		// массив для символов
unsigned char PTR;		// указатель буфера индикатора 
unsigned char  buffer_ind;	// буфер индикатора
static volatile near unsigned int    TMR1        @ 0x00E;		                                    
unsigned char led7seg[12] = {0x3F,//0
						 0x06,	//1
						 0x5B,	//2
						 0x4F,	//3
						 0x66,	//4
						 0x6D,	//5
						 0x7D,	//6
						 0x07,	//7
						 0x7F,	//8
						 0x6F,	//9
						 0x00,	//space
						 0x78};  //       E


void main ( void )
{	int i;
OPTION = 1 ;		// Подтяжка вкл
TRISA = 1 ;		// Вход
TRISD = 1 ;		// 7 сег дисплай
TRISB = 0 ; 		// Катоды
PORTB = 0; 
ADCON1 = 0b00000111 ; // ПортА цифровои
CMCON =  0b00000111 ; // Компаратор выкл
//Инициализация прерываний от TMR1 пред 1:1,
//Internal clock (FOSC/4), генератор офф
      TMR1 = 65535 - 5000;   // Таймер на 10000 циклов
TMR1ON = 1 ;                    // Вкл. TMR1
TMR1IE = 1 ;                    //  прерывание от TMR1
PEIE = 1 ;      //  прерывания от периферийных устройств
GIE =  1	;	//  глобальные прерывания
i = 123;
dig[0] = 10;
dig[1] = i /100;
 dig[2]= (i %100)/10;
 dig[3] = i %10;
while(1){ }
}
void interrupt isr (void)
{
static unsigned char ind_num;	// Номер индикатора

	TMR1IF=0;	// Сбрасываем флаг
	TMR1 = 65537 - 5000 ; 
       PORTD = 0;      // очистим индикатор
       port_catod= 1<<port_catod;        // установим следующее знакоместо для отображения
 PORTD = led7seg[dig[PTR]];         // выведем на индикатор
       PTR++;          // установим указатель на следующий символ

       if(PTR >4) { PTR = 0;PORTB = 0; } //проверим, не кончился ли массив для вывода на индикатор

       T0IF = 0;       // сбросим флаг прерывания

       T0IF = 0;       // сбросим флаг прерывания



}

Происходит какои-то сбои при загрузке значений из массива led7seg, потом и при выборе второго знакоместа перепрыгивает на 5ое.

test_ds_pic.zip

Не цитируите полностью предыдущее сообщение!!!

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

port_catod= 1<<port_catod;
Уберите это немедленно, пока никто не увидел :)

Наверное тут хотели написать так - port_catod= 1<<PTR; :rolleyes:

Прогнал в симуляторе, всё нормально работает.

Где Вы видите косяки ?

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

А прикол вот в чем при загрузке из массива символа "2" и "3" , то есть 5В и 4F загружается в порт 5А и 4E , что на один меньше, прошивку загружаю в пик на макете, естественно сегмент А не горит.

Загружал прошивку из сампла от микроэлектроники, тоже с динамическои индикацией, там все работает.

Не цитируите полностью предыдущее сообщение!!!

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

Немного еще подправил и выяснил, что нормально выгружается из массива с символами только 1 и 4 , остальные на 1 меньше.

прикрепляю всю папку с проектом, на подключенные фаилы не обращаите внимания.

test_pic.rar

Не цитируите полностью предыдущее сообщение!!!

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

Да, а как же оно тогда хоть как то работало? Ведь три из четырех знакомест, без сегмента А светились???

Впрочем не столь важно, теперь все работает

	# include <pic.h>	// PIC16F877A
# include "delay.h"
__CONFIG ( XT & WDTDIS & PWRTEN & BOREN & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT ) ;
# define 		_XTAL_FREQ 4000000  // Определить частоту МК
# define 		bitset(var, bitno) ((var) |= 1UL << (bitno))
# define 		bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
// ОПРЕДЕЛИТЬ ПИНЫ
# define 	DQ		RA2
# define  port_catod PORTB
// ПРОТОТИПЫ

// ПЕРЕМЕННЫЕ
unsigned char dig[4];		// массив для символов
unsigned char PTR;		// указатель буфера индикатора 
unsigned char  buffer_ind;	// буфер индикатора
static volatile near unsigned int    TMR1        @ 0x00E;		                                    
unsigned char led7seg[12] = {0x3F,//0
						 0x06,	//1
						 0x5B,	//2
						 0x4F,	//3
						 0x66,	//4
						 0x6D,	//5
						 0x7D,	//6
						 0x07,	//7
						 0x7F,	//8
						 0x6F,	//9
						 0x00,	//space
						 0x78};  //       E


void main ( void )
{	int i;
OPTION = 1 ;		// Подтяжка вкл
TRISA = 1 ;		// Вход
TRISD = 0 ;		// 7 сег дисплай
TRISB = 0 ; 		// Катоды
PORTB = 0; 
ADCON1 = 0b00000111 ; // ПортА цифровои
CMCON =  0b00000111 ; // Компаратор выкл
//Инициализация прерываний от TMR1 пред 1:1,
//Internal clock (FOSC/4), генератор офф
      TMR1 = 65535 - 5000;   // Таймер на 10000 циклов
TMR1ON = 1 ;                    // Вкл. TMR1
TMR1IE = 1 ;                    //  прерывание от TMR1
PEIE = 1 ;      //  прерывания от периферийных устройств
GIE =  1	;	//  глобальные прерывания
i = 4567;
dig[0] = i/1000;
dig[1] = (i %1000)/100;
 dig[2]= (i %100)/10;
 dig[3] = i %10;
while(1){ }
}
void interrupt isr (void)
{

	TMR1IF=0;	// Сбрасываем флаг
	TMR1 = 65537 - 5000 ; 
       PORTD = 0;      // очистим индикатор
       port_catod= 1<<PTR;        // установим следующее знакоместо для отображения
 PORTD = led7seg[dig[PTR]];         // выведем на индикатор
       PTR++;          // установим указатель на следующий символ

       if(PTR >4) { PTR = 0;PORTB = 0; } //проверим, не кончился ли массив для вывода на индикатор

       T0IF = 0;       // сбросим флаг прерывания




}

Изменено пользователем Andrey_Ch8

Не цитируите полностью предыдущее сообщение!!!

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

Привет всем!

Продолжаю изучение MicroC но теперь уже для PIC24 и PIC30,PIC33.Указал генерацию соff файла в MicroC, в PROTEUS указал к нему путь и.... Вылазит ошибка с таким вот содержимым.

[PIC24LP] Invalid word address range 0x7FFFFFFF-00000022 in program data.

Internal Exception:access violation in module 'LOADERS.DLL'.

Когда указываю путь к HEX программа работает.

Дллку скачал и скопировал в sistem32,не помогло.

Может кто сталкивался подскажет, проект прилагаю с простейшей программкой.

PIC24.rar

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

Нашол инфу,что MicroC для PIC24 и PIC30,33 генерит корявый coff когда это исправять не понятно.Жаль я так к нему привык придется переходить на MPLAB и С30 или HI-Tech.

Кто то может подскажет инструкцию на русском по этим вещам,создание проекта как их совместно использовать?

Спасибо!

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

я просто мимо проходил... COFF это common object file format - и предназначен для хранения файлов .obj и библиотек .lib

а исполнять процессор должен прошивку из HEX-файла, поэтому падение симулятора на coff по-моему закономерно в данном случае.

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

Нашол инфу,что MicroC для PIC24 и PIC30,33 генерит корявый coff когда это исправять не понятно.Жаль я так к нему привык придется переходить на MPLAB и С30 или HI-Tech.

Кто то может подскажет инструкцию на русском по этим вещам,создание проекта как их совместно использовать?

Спасибо!

вот тут есть http://piclist.ru/learning_PIC24_1/learning_PIC24_1.html

Не цитируите полностью предыдущее сообщение!!!

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

Здравствуите, у меня проблема, пик не показывает температуру,

	# include <pic.h>	// PIC16F877A
# include "delay.h"
__CONFIG ( XT & WDTDIS & PWRTEN & BOREN & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT ) ;
# define 		_XTAL_FREQ 4000000  // Определить частоту МК
# define 		bitset(var, bitno) ((var) |= 1UL << (bitno))
# define 		bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
// ОПРЕДЕЛИТЬ ПИНЫ и КОНСТАНТЫ
#define D_RiseSpace 5        // Rise Time + Minimum Space (3uS+1uS absolute min)
# define  D_TRIS   TRISA2
# define 	DQ		RA2
# define  port_catod PORTB
// ПРОТОТИПЫ
	char D_Reset(void);
void D_Write(unsigned char);
char D_Read(void);
// ПЕРЕМЕННЫЕ
unsigned char Data;// для записи в DS
unsigned char  sec;
signed char Temper;
bit D_Data, flag;
unsigned char dig[4];		// массив для символов
unsigned char PTR;		// указатель буфера индикатора 
static volatile near unsigned int    TMR1        @ 0x00E;		                                    
unsigned char led7seg[12] = {0x3F,//0
						 0x06,	//1
						 0x5B,	//2
						 0x4F,	//3
						 0x66,	//4
						 0x6D,	//5
						 0x7D,	//6
						 0x07,	//7
						 0x7F,	//8
						 0x6F,	//9
						 0x00,	//10 space
						 0x78};  //  11     E


void main ( void )
{	unsigned char  err;
OPTION = 1 ;		// Подтяжка вкл
TRISA = 1 ;		// Вход
TRISD = 0 ;		// 7 сег дисплай
TRISB = 0 ; 		// Катоды
PORTB = 0; 
ADCON1 = 0b00000111 ; // ПортА цифровои
CMCON =  0b00000111 ; // Компаратор выкл
//Инициализация прерываний от TMR1 пред 1:1,
//Internal clock (FOSC/4), генератор офф
      TMR1 = 65535 - 5000;   // Таймер на 5000 циклов
TMR1ON = 1 ;                    // Вкл. TMR1
TMR1IE = 1 ;                    //  прерывание от TMR1
PEIE = 1 ;      //  прерывания от периферийных устройств
GIE =  0	;	//  глобальные прерывания
err = D_Reset();
if (err)// если ошибка
	{dig[0] = 11; dig[1] = 10; dig[2] = 1; dig[3] = 10;while(1){}}// E1
else 
{
Data = 0x0C; D_Write(Data);// Активируем запись в конфиг регистр
Data = 0x01; D_Write(Data);//запишем 00000001-одноразовое преобразование
D_Reset();
Data = 0xEE; D_Write(Data);// Запустим преобразование

Data = 0xAA;D_Write(Data);// активируем чтение температуры
Temper =D_Read(); 
/*if(Temper<0)
	{dig[3] = 0x40;}
else {dig[3] = 10;}*/
dig[2] = Temper/10;
dig[1] = Temper%10;
dig[0] = 10;// пробел
 }
GIE = 1;
while(1){}



}
unsigned char D_Reset(){
unsigned char D_Presense;
D_TRIS = 1; DQ = 0;
D_TRIS = 0; DelayUs(480);// импульс сброса
D_TRIS = 1; DelayUs( 60 );// задержка до импульса присутствия
D_Presense = DQ;// 0 - присутствует, 1- ошибка
DelayUs(400)// Задержка до конца
if ( D_Presense == 1) {return (1);}// если ошибка
	else {return (0);}                      
}
void D_Write(unsigned char){
 char count=8;
	for(;count>0;count--)
	{
 	D_Data= Data & 0x01;    //-- Get LSB

 	//-- Write the bit to the port
 	DQ=0;
 	D_TRIS=0;               //-- Lower the port
 	DelayUs(5);             //-- Time slot start time
 	D_TRIS=D_Data;          //-- Output the data to the port
  DelayUs(50);            //-- Finish Timeslot
 	DelayUs(5);

 	D_TRIS=1;               //-- Ensure Release of Port Pin

 	//-- Delay Between Bits
 	DelayUs(D_RiseSpace);             //-- Recovery time between Bits

 	//-- Prep Next Bit
 	Data=Data>>1;           //-- Shift next bit into place
	}
	DelayUs(D_RiseSpace);    //-- Rise time + Min Space
}
/*************************************************/
char D_Read(void)
{
	char count=8,data=0;
	for(;count>0;count--)
 {
	 //-- Write the bit to the port
 	DQ=0;
 	D_TRIS=0;               //-- Lower the port
	 DelayUs(5);             //-- Time slot start time
 	D_TRIS=1;               //-- Release port for reading
 	DelayUs(5);             //-- Get close to center of timeslot
 	D_Data=DQ;           //-- Read the data bit in
	 DelayUs(50);            //-- Finish the timeslot

 	//-- Put data into the byte
 	data = data >> 1;        //-- Shift previous bits across
 	if(D_Data==1)            //-- If data was high then add High bit to data
 	{
 	 data +=0x80;
 	}
 	//-- Delay Between Bits
 	DelayUs(D_RiseSpace);             //-- Recovery time between Bits
	}
	DelayUs(D_RiseSpace);    //-- Rise time + Min Space
	return(data);
}
/***********************************************/
void interrupt isr (void)
{		if (flag)
	{sec--;
		if(sec ==0)
		{	flag = 0; }
	}
	TMR1IF=0;	// Сбрасываем флаг
	TMR1 = 65537 - 5000 ;
	TRISA = 1 ;		// Вход
TRISD = 0 ;		// 7 сег дисплай
TRISB = 0 ; 		// Катоды 
       PORTD = 0;      // очистим индикатор
       port_catod= 1<<PTR;        // установим следующее знакоместо для отображения
 PORTD = led7seg[dig[PTR]];         // выведем на индикатор
       PTR++;          // установим указатель на следующий символ

       if(PTR >4) { PTR = 0;PORTB = 0; } //проверим, не кончился ли массив для вывода на индикатор

       T0IF = 0;       // сбросим флаг прерывания

При этом индикация отлажена и в настроике не нуждается, если сделать

Temper = 0x19 // 

или любое положительное число , то оно хорошо отображается

если

Temper = D_Read();

, то показывает 00

Не цитируите полностью предыдущее сообщение!!!

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

Во первых. Где пауза между командой преобразования и командой чтения температуры ?

Во вторых. У Вас кусок программы, отвечающий за работу датчика, выполняется всего 1 раз.

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

Компиль ругался на запись DelayMs(750), но я только что добавил Delay.c в проект и заработало , хотя и ноли показывает. 1 раз это на стадии отладки, потом буду проверять раз в пять секунд, все таки это не термометр будет, пробовал убрать датчик , пик пытается показать Е1, показывает крякозябрами.

Добавил еще

	if (err)// если ошибка
	{dig[0] = 11; dig[1] = 10; dig[2] = 1; dig[3] = 10;GIE = 1;while(1){}}// E1
else 

Да чуть не забыл ,у меня датчик DS1821.

Изменено пользователем Andrey_Ch8

Не цитируите полностью предыдущее сообщение!!!

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

Возможно у Вас проблемы с задержками. Попробуйте в отладчике посмотреть время выполнения DelayUs(); как с большим значением (500), так и с маленьким (5).

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

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

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

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

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

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

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

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

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

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

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

×
×
  • Создать...