Форум по микроконтроллерам: Начинаем Изучать Си - Форум по микроконтроллерам

Перейти к содержимому

Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

Начинаем Изучать Си HI-TECH

#1 Пользователь офлайн   Alex 

  • Активный участник
  • PipPipPip
  • Группа: Администратор
  • Сообщений: 320
  • Регистрация: 08 Август 08
  • Пол:Мужчина
  • Город:http://forum.eldigi.ru/

Отправлено 18 Ноябрь 2010 - 13:30

И так, начнём.
Так как пользуюсь я компиляторм HI-TECH (чего и Вам советую), опишу начало работы с ним.
Качаем компилятор HI-TECH PICC18 (для 18 серии), устанавливаем его.
Создаём папку для проекта, назовём её к примеру ”leds”. Открываем MPlab (надеюсь он у Вас уже установлен). Создаем проект, меню project->project wizard…
Прикрепленное изображение: step_1.jpg
Перед Вами вылезает окно с приветствием.
Прикрепленное изображение: step_2.jpg
Мысленно приветствуемся и жмём Далее

Вылезает окно выбора контроллера. Выбираем PIC18F252 и жмём Далее
Прикрепленное изображение: step_3.jpg
Далее будет окно с выбором компилятора.
В списке Active Toolsuite нужно выбрать HI-TECH PICC18
Прикрепленное изображение: step_4.jpg
Жмём Далее.

Перед Вами окно с вводом имени проекта и выбором пути к директории проекта.
Название проекта пишем leds и выбираем путь к созданной нами директории.
Прикрепленное изображение: step_5.jpg
Жмём Далее.
Вылезает окно с предложением добавить в проект файлы. Нам добавлять ничего не нужно, по этому жмём Далее и в следующем окне жмём Готово.
Всё, проект создан.
Теперь нам нужно добавить в него новый файл. Лезем в меню File->Add New File to Project
Прикрепленное изображение: step_6.jpg
вибираем нашу папку и пишем в имени файла main.c
Прикрепленное изображение: step_7.jpg
Жмём Сохранить.

Теперь он добавлен в список файлов проекта и вылезло окно редактора.
Прикрепленное изображение: step_8.jpg
Пишем первую программу.
Нашей программой будет бегущий светодиод на порте В.

Первой строчкой нашей программы будет
#include	"pic18.h"

Этим мы подключим к проекту нужный файл, в котором описаны все регистры спец. назначения нашего МК.
Далее задаём биты конфигурации
__CONFIG(1, 0x02FF);	
__CONFIG(2, 0x0EFF);	
__CONFIG(4, 0xFF80);

Осциллятор – XT, WDT выключен и т.д… Подробнее о конфигах можно узнать в даташите

Теперь напишем функцию с которой наша программа будет начинать выполняться. Она всегда имеет имя main().
void main(void)
{



}

Затем, в этой функции проинициализируем порты
TRISB=0;		//  Все пины порта В на выход
PORTB=0;	  //   Выводим в порт В все нули

Далее нам нужно программу зациклить, так как она ни когда не должна закончиться. Делается это с помощью оператора while(). Он выполняет код, находящийся в фигурных скобках {}, пока в круглых скобках () условие равно 1.
while(1) // Бесконечный цикл
{


}

Теперь нам нужно сделать задержку, с которой у нас будут бегать светодиоды.
Для этого создаём новую функцию, перед main(). Назовём её delay().
И пишем в ней код :
unsigned long i;	// Создаём 4-х байтную переменную

i=100000;	// Присваиваем переменной значение 100 000
while(i>0)	// Пока переменная i больше ноля
{
  i--;		// Вычитаем из переменной 1, т.е. декремент.
}
При частоте кварца 10 Мгц, задержка получилась приблизительно 0.5 Сек. Если кто-то хочет по точнее, поиграйтесь с числом 100000.

Едем дальше…
Бегущий огонь будем делать методом сдвига 1-чки в порте. Запишем в 0-вой бит порта 1-чку, и будем её двигать влево пока порт не станет равным нолю. И так по кругу.

Переходим к главному циклу (который бесконечный) и пишем в нём код:
if(PORTB==0) 
{
PORTB=1;
}
Этим условием мы проверяем порт на 0. И если условие верно, записываем в порт 1-цу.
Далее вызываем ф-ию задержки
delay();
Затем сдвигаем порт влево.
PORTB = PORTB<<1;


В итоге main.c у нас примет такой вид:

#include	"pic18.h"

__CONFIG(1, 0x02FF);	
__CONFIG(2, 0x0EFF);	
__CONFIG(4, 0xFF80);


void delay(void)
{
unsigned long i;	// Создаём 4-х байтную переменную

i=100000;	// Присваиваем переменной значение 100 000
while(i>0)	// Пока переменная i больше ноля
{
  i--;		// Вычитаем из переменной 1, т.е. декремент.
}
}


void main(void)
{

TRISB=0;		//  Все пины порта В на выход
PORTB=0;	  //   Выводим в порт В все нули


while(1) // Бесконечный цикл
{
   if(PORTB==0)// Проверяем порт на 0, 
   {
   PORTB=1;  // и если равен, то пишем туда 1-чку
   }
 delay();	// Вызываем задержку
 PORTB = PORTB<<1;  // Двигаем порт влево на 1 позицию
}
}

Затем жмём в Мплабе кнопку Build All и у нас готовая прошивка, которую можно опробовать в железе.

Прикрепляю только что созданный нами проект + проект протеуса, что бы посмотреть наглядно работу программы.
Прикрепленный файл  leds.rar (25,5К)
Количество загрузок:: 351
Вот и всё, пробуем, задаём вопросы….
0

#2 Пользователь офлайн   ELL 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 1
  • Регистрация: 23 Ноябрь 10

Отправлено 23 Ноябрь 2010 - 09:22

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

#3 Пользователь офлайн   anywhere 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 23 Ноябрь 10

Отправлено 23 Ноябрь 2010 - 09:27

Если можно, то немного назад - начать со структуры, схемы или формы построения программы в Си. Типа такого :
1.Присоединненные файлы
2.Конфигурация
3.Объявление переменных
4. Константы
5. .................
Хотелось бы сразу не делать ошибок в оформлении программ
0

#4 Пользователь офлайн   Alex 

  • Активный участник
  • PipPipPip
  • Группа: Администратор
  • Сообщений: 320
  • Регистрация: 08 Август 08
  • Пол:Мужчина
  • Город:http://forum.eldigi.ru/

Отправлено 23 Ноябрь 2010 - 11:57


0

#5 Пользователь офлайн   Alex 

  • Активный участник
  • PipPipPip
  • Группа: Администратор
  • Сообщений: 320
  • Регистрация: 08 Август 08
  • Пол:Мужчина
  • Город:http://forum.eldigi.ru/

Отправлено 29 Ноябрь 2010 - 20:45

Поддержка прерываний

Компилятор PICC полностью поддерживает прерывания контроллера. Таким образом вам
не придется писать ни строчки ассемблерного кода при написании полноценных
обработчиков прерываний. Для описания функции, которая и будет являться обработчиком,
необходимо воспользоваться квалификатором interrupt. Эта функция будет напрямую
вызвана в случае возникновения прерывания. Но компилятор оформит эту функцию
специальным образом. Прежде всего будут сохранены и восстановлены все регистры,
которые были задействованы в обработчике и, кроме того, для выхода из функции бкдет
использоваться оператор retfie.
Функция обработчик прерываний должна возвращать значение типа void и не должна
иметь аргументов. Ее нельзя вызывать непосредственно из программы, но она может
обращаться к другим функциям, с чем надо проявлять особую осторожность.
Вот пример простейшего обработчика прерываний:
long tick_count;
void interrupt tc_int(void)
{
  if (TMR1IF){	// Прерывание от TMR1 ?
	TMR1IF=0;	// Сбросим флаг
	++tick_count; // Увеличим переменную tick_count на 1
  }
}

Инициализация :
TMR1ON=1;  // Вкл. TMR1
TMR1IE=1;	// Разрешили прерывание от TMR1

PEIE = 1;	// Разрешить все прерывания от периферийных устройств
GIE=1;		// Разрешить прерывания глобально

0

#6 Пользователь офлайн   CAHEK 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 3
  • Регистрация: 05 Декабрь 10

Отправлено 05 Декабрь 2010 - 08:59

Автору огромное спасибо.Наконец то нашол то,что хотел.С Мплабом дружу с год,а вот на Си перейти не получалось,теперь реальный шанс!!!!!!!!!
0

#7 Пользователь офлайн   CAHEK 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 3
  • Регистрация: 05 Декабрь 10

Отправлено 05 Декабрь 2010 - 12:50

Alex, в чем может быть проблема? :rolleyes:

Прикрепленные изображения

  • Прикрепленное изображение: 2233.JPG

0

#8 Пользователь офлайн   CAHEK 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 3
  • Регистрация: 05 Декабрь 10

Отправлено 05 Декабрь 2010 - 13:42

УРА!!!!!!!!!!!!!
ЗАРАБОТАЛА!!!!!!!Косяк сидел,как всегда в тупости,надо четко пользовать инструкцию по инсталяции.В моем случае путь к папкам. :rolleyes:
0

#9 Пользователь офлайн   anywhere 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 23 Ноябрь 10

Отправлено 16 Март 2011 - 08:14

Помогите разобраться с формальными и фактическими переменными.
Я так понимаю, что программа резервирует область памяти для формальной переменной,
потом копирует в эту область фактическую переменную (или результат вычисления выражения),
дальше производит действия с копией фактической переменной, но саму фактическую переменную
не изменяет ?
Вот небольшой отрывок программы :
unsigned char _decyat,edin,_des;
unsigned int tmp1_ADC;			   //фактическая переменная


void main(){ 
   init_MCU();
   tmp1_ADC = _ADC();
   preobraz(tmp1_ADC);
 }


/*Преобразование из двоичного в двоично-десятичный код*/
unsigned int preobraz(unsigned int b){
	  unsigned int p;
	  extern unsigned char _decyat,edin,_des;
	   b= (int)((float)b*5/1024*delitel);
	  _decyat  = b/100;
	   p = b%100;
	  edin = p/10;
	  _des = p%10;
 }

Из вышесказанного следует, что tmp1_ADC не изменяется?
А если так :
/*Преобразование из двоичного в двоично-десятичный код*/
unsigned int preobraz(unsigned int b){
	  unsigned int p;
	  extern unsigned char _decyat,edin,_des;
	  [color="#FF0000"][b]b[/b][/color] = (int)((float)b*5/1024*delitel);
	  _decyat  = b/100;
	   p = b%100;
	  edin = p/10;
	  _des = p%10;
	  return b;							   //<--- функция изменит фактическую tmp1_ADC ?
 }

или всетаки надо так :
void main(){ 
   init_MCU();
   tmp1_ADC = _ADC();
   tmp1_ADC= preobraz(tmp1_ADC);
}

0

#10 Пользователь офлайн   ATAMAN2000 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 3
  • Регистрация: 29 Ноябрь 11

Отправлено 29 Ноябрь 2011 - 22:08

Просмотр сообщенияanywhere (16 Март 2011 - 08:14) писал:

Помогите разобраться с формальными и фактическими переменными.
Я так понимаю, что программа резервирует область памяти для формальной переменной,
потом копирует в эту область фактическую переменную (или результат вычисления выражения),
дальше производит действия с копией фактической переменной, но саму фактическую переменную
не изменяет ?
Вот небольшой отрывок программы :
<!--c1--><div class='codetop'>Код</div><div class='codemain'><!--ec1-->unsigned char _decyat,edin,_des;
unsigned int tmp1_ADC; //фактическая переменная


void main(){
init_MCU();
tmp1_ADC = _ADC();
preobraz(tmp1_ADC);
}


/*Преобразование из двоичного в двоично-десятичный код*/
unsigned int preobraz(unsigned int :({
unsigned int p;
extern unsigned char _decyat,edin,_des;
b= (int)((float)b*5/1024*delitel);
_decyat = b/100;
p = b%100;
edin = p/10;
_des = p%10;
}<!--c2--></div><!--ec2-->
Из вышесказанного следует, что <i>tmp1_ADC</i> не изменяется?
А если так :
<!--c1--><div class='codetop'>Код</div><div class='codemain'><!--ec1-->/*Преобразование из двоичного в двоично-десятичный код*/
unsigned int preobraz(unsigned int B){
unsigned int p;
extern unsigned char _decyat,edin,_des;
b = (int)((float)b*5/1024*delitel);
_decyat = b/100;
p = b%100;
edin = p/10;
_des = p%10;
return b; //<--- функция изменит фактическую tmp1_ADC ?
}<!--c2--></div><!--ec2-->
или всетаки надо так :
<!--c1--><div class='codetop'>Код</div><div class='codemain'><!--ec1-->void main(){
init_MCU();
tmp1_ADC = _ADC();
tmp1_ADC= preobraz(tmp1_ADC);
}<!--c2--></div><!--ec2-->

Не знаю кто переводил данную подшивку к программе mikroc на переведено грамотно и доступно.
А вобще Си и PIC очень совместимы.
0

#11 Пользователь офлайн   Анубис 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 2
  • Регистрация: 02 Декабрь 11

Отправлено 03 Декабрь 2011 - 11:11

Уважаемый Alex, сделал все как вы описали, загрузил ваш проект, он открылся. Но когда я попытался уменьшить время задержки в два раза i=50000 и его скомпилить(F10), вышло следующее сообщение:
Executing: "C:\Program Files\Microchip\MPLAB IDE\HI-TECH PICC18 v9.50 PL3\PICC-18\9.50\bin\aspic18.exe" -C -E"main.cce" "main.c" -O"main.obj" -Zg9 -O -ASMLIST -Q -MPLAB -18F252 Advisory[1207] : some of the command line options you are using are now obsolete Advisory[1208] : use --help option or refer to the user manual for option details : 0: (1215) An error, warning or message was generated, but no description is available (error) : 0: (1215) An error, warning or message was generated, but no description is available (error) : 0: (1215) An error, warning or message was generated, but no description is available (error) : 0: (1215) An error, warning or message was generated, but no description is available (error) : 0: (1215) An error, warning or message was generated, but no description is available (error) : 0: (1215) An error, warning or message was generated, but no description is available (error) : 0: (1215) An error, warning or message was generated, but no description is available (error) Halting build on first failure as requested. BUILD FAILED: Sat Dec 03 15:03:09 2011
Что я сделал не так?

Разобрался, вроде, проблема была в четком следовании инструкциям по установке компиллятора.
0

#12 Пользователь офлайн   skleptik 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 1
  • Регистрация: 19 Сентябрь 13

Отправлено 19 Сентябрь 2013 - 09:10

Здравствуйте Помогите разобраться!

Переписал программу из первого поста, под pic12f629.
В мплабе вроде работает.
В протеусе светодиоды не моргают.
Вот код

#include "pic12f629.h"

__02007h(){0x3FC4;}
void delay (void)
{
CMCON=0x07;
unsigned long i;
i=10000;
while (i>0)
{
i--;
}
}

void main (void)
{
TRISIO =0x8;
GPIO =0;

while(1)
{

if (GPIO==0)
{
GPIO=1;
}
delay();
GPIO = GPIO<<1;
}
}

Что не так ?
0

Поделиться темой:


Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей