|
Генератор импульсов на Attiny 45, Прямоугольный сигнал. Как получить? |
|
|
|
Oct 30 2012, 18:56
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-10-12
Пользователь №: 74 169

|
Форумчане, здравствуйте! Простите за нубский вопрос. Спасите меня. Сам я разработчик-схемотехник, но в программировании микроконтроллеров понимаю мало, а дело срочное. Итак, у меня есть всё аппаратное и программное обеспечение: распаянный на колодке контроллер Attiny45 без кварца, программатор SM-4, софт asisp для чтения и записи флеш и еепром, (т.е. сам я прошить-считать-стереть и.т.д. умею). Есть установленная Atmel Studio 6.0. Есть всё. Знаний про написание кода нет. Требуется: получить с 2х ножек контроллера меандр скважностью 2, частота 50 кГц. Меандры должны идти в противофазе. т.е. если на одной ноге 0 то на другой в это время должен быть 1. Вот и всё, вот и вся задача. Подал питание - и нарубается меандр. Я чувствую, что это просто, а Си и Ассемблер забыл)))) Или чем вы его там пишите... Ещё конкретнее: как написать программу, компилировать, а лучше, простите за наглость, дайте текст или уже готовую прошивку, но с исходником, чтобы я мог менять частоту и длительность импульсов. Горю, ребята., спасите, на самостоятельное изучение этого вопроса нет времени, но я займусь. Пишите прямо тут, а ещё лучше - прямо мне в мыло ofts@yandex.ru Спасибо всем заранее.
|
|
|
|
|
Oct 30 2012, 20:44
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(mamuka60 @ Oct 30 2012, 21:56)  Пишите прямо тут, а ещё лучше - прямо мне в мыло ofts@yandex.ru Если допустим небольшой джиттер и вам нужно не ровно 50 КГц, а плюс-минус доли процента, то вот вам готовый пример: http://zalil.ru/33910003Кварц на 10 МГц, компилятор - CodeVision (начните с него, для новичка он подходит идеально). После включения питания на PORTB.0 и PORTB.1 появятся противофазные меандры. Этот пример - простейший, по прерыванию от переполнения таймера программно инвертируются две ножки. Если указанные мной выше особенности этого простейшего проекта для вас неприемлемы, то вам придется изучить, как работают таймеры и как их запрограммировать для выдачи нужных вам сигналов. Литература по программированию AVR вот здесь: http://lord-n.narod.ru/walla.htmlP.S. Можно вообще без прерываний - цикл с delay(). Или даже вместо delay() использовать несколько десятков "nop" - ов, поскольку вам нужна довольно большая частота. Проще не придумать: Код PORTB.0 = 0; PORTB.1 = 1; while(1) { PORTB = (PORTB ^ 0x03); delay_us(10); } или вот так: Код PORTB.0 = 0; PORTB.1 = 1; while(1) { PORTB = (PORTB ^ 0x03); #asm("nop") #asm("nop") ... #asm("nop") }
|
|
|
|
|
Oct 31 2012, 19:26
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-10-12
Пользователь №: 74 169

|
[quote name='kovigor' date='Oct 31 2012, 00:44' post='1107114'] Если допустим небольшой джиттер и вам нужно не ровно 50 КГц, а плюс-минус доли процента, то вот вам готовый пример:
Спасибо, товарищ, выручил.
|
|
|
|
|
Nov 1 2012, 06:57
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-10-12
Пользователь №: 74 169

|
Цитата(kovigor @ Nov 1 2012, 01:46)  Подошло такое решение ? Поскольку кварца на 10 мГц у нас нет, мы прошили Вашим файлом HEX контроллер, и всё заработало. НО! - не на частоте 50 кГц, как надо, а на частоте 33 кГЦ. Как это изменить? Второй вопрос. Мы скачали рекомендуемый Вами CodeVision, и попробовали вставить туда приведённые Вами кусок (только его) PORTB.0 = 0; PORTB.1 = 1; while(1) { PORTB = (PORTB ^ 0x03); delay_us(10); } но в данном случае компилятор ругается вот так, что мол он не понимает delay_us А AtmelStudio ругается так: Error 1 expected ';' before numeric constant C:\Users\Отд 120\Documents\Atmel Studio\GccApplication1\GccApplication1\GccApplication1.c 15 13 GccApplication1 И ещё одна деталь. Прилагаю файл, как должны выглядеть осциллограммы. Скважность там не 2, а 2.5
_____________.pdf ( 21.62 килобайт )
Кол-во скачиваний: 285
|
|
|
|
|
Nov 1 2012, 08:14
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 19-06-07
Из: Челябинск
Пользователь №: 28 542

|
Цитата(mamuka60 @ Nov 1 2012, 10:57)  PORTB.0 = 0; PORTB.1 = 1; while(1) { PORTB = (PORTB ^ 0x03); delay_us(10); } но в данном случае компилятор ругается вот так, что мол он не понимает delay_us Попробуйте перед delay_us(10); поставить подчеркивание _
Сообщение отредактировал Valek - Nov 1 2012, 08:15
|
|
|
|
|
Nov 1 2012, 08:33
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(mamuka60 @ Nov 1 2012, 10:57)  Поскольку кварца на 10 мГц у нас нет, мы прошили Вашим файлом HEX контроллер, и всё заработало. НО! - не на частоте 50 кГц, как надо, а на частоте 33 кГЦ. Как это изменить? Второй вопрос. Мы скачали рекомендуемый Вами CodeVision, и попробовали вставить туда приведённые Вами кусок (только его) но в данном случае компилятор ругается вот так, что мол он не понимает delay_us И правильно делает, что ругается. Вам надо в самых первых строках программы включить в нее файл "delay.h": Код #include <delay.h> Осциллограмму посмотрел. Вам хорошо подойдет вариант не с прерыванием, а с "nop"ами: Код PORTB.0 = 0; PORTB.1 = 0; while(1) { //Отрабатываем первые 2 мкС #asm("nop") //Задержка на первые 2 мкС. #asm("nop") //Насколько я помню, "nop" выполняется за один машинный цикл. ... #asm("nop") //Исходя из этого рассчитайте или подберите с помощью осциллографа нужное вам кол-во "nop"ов
//Теперь отрабатываем 8 мкС PORTB.0 = 1; #asm("nop") #asm("nop") #asm("nop") ... #asm("nop")
//Теперь отрабатываем 2 мкС PORTB.0 = 0; #asm("nop") #asm("nop") ... #asm("nop")
//Теперь отрабатываем 8 мкС PORTB.1 = 1; #asm("nop") #asm("nop") #asm("nop") ... #asm("nop")
//Теперь отрабатываем 2 мкС, для чего начинаем новый виток цикла PORTB.1 = 0;
//Один цикл колебаний завершен. Выполняем новый цикл, и так продолжаем, пока не выключат питание } Таким образом можно весьма точно подстроить все временные соотношения осциллограммы. Попробуйте, должно заработать ... P.S. Выяснил. "nop" выполняется за один период резонатора (кварца). Соотетственно, с такой точностью и можно подстраивать осциллограмму. Т.е., для 10 МГц это будет 100 нС, и для 2-х мкС потребуются 20 "nop"ов ... P.P.S. Компилировать советую в CodeVision. Выкладываю проект: http://zalil.ru/33914939
|
|
|
|
|
Nov 1 2012, 13:02
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(mamuka60 @ Oct 31 2012, 03:56)  Подал питание - и нарубается меандр...
 РЈРСВВВВеньшено Р В Р’В Р СћРІР‚ВВВР С• 53%
676 x 408 (2.41 килобайт)
|
В tiny45 есть timer1 с такой функцией. Программировать, т.е. составлять алгоритм, вообще не нужно. Текст программы - лишь инициализация таймера, портов в/в. Частота, скважность и dead time - всё записывается в регистры управления timer1 и deadtime generator, далее сигналы на выводах формируются аппаратно. Программа - пустой бесконечный цикл.
|
|
|
|
|
Nov 1 2012, 19:00
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-10-12
Пользователь №: 74 169

|
Спасибо всем, друзья! Завтра попробуем. Выложу результат. Ещё раз спасибо всем.
|
|
|
|
|
Nov 2 2012, 15:23
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-10-12
Пользователь №: 74 169

|
Большое спасибо всем и особенно kovigor, мы получили то, что хотели. мы освоили фокусы с нопами и ещё, что особенно расширяет влияние на частоту, комбинации с fuse - битами (как-то так). Всё получили без применения внешнего резонатора (кварца). Правда, пришлось поэкспериментировать, но в целом, инструмент освоен, начало положено, рухнула глухая стена непонимания процессов. Но жажда эксперимента заставляет меня задать вопрос: какую операцию в код надо вставить, чтобы при появлении, например, на portb2 логической 1, программа глохла и колебания выключались? Или, например, при появлении 1 на portb2, программа перескакивала, например, на другую подпрограмму, в которой, например, мы могли бы задать другое колебание?
|
|
|
|
|
Nov 2 2012, 15:28
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(mamuka60 @ Nov 2 2012, 17:23)  Но жажда эксперимента заставляет меня задать вопрос: какую операцию в код надо вставить, чтобы при появлении, например, на portb2 логической 1, программа глохла и колебания выключались? Или, например, при появлении 1 на portb2, программа перескакивала, например, на другую подпрограмму, в которой, например, мы могли бы задать другое колебание? Код if (PINB&(1<<1)) {// на PB1 - 1 // вариант действий 1 } else {// на PB1 - 0 // вариант действий 0 }
|
|
|
|
|
Nov 2 2012, 16:18
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(mamuka60 @ Nov 2 2012, 18:23)  Большое спасибо всем и особенно kovigor, мы получили то, что хотели. мы освоили фокусы с нопами и ещё, что особенно расширяет влияние на частоту, комбинации с fuse - битами (как-то так). Всё получили без применения внешнего резонатора (кварца). Правда, пришлось поэкспериментировать, но в целом, инструмент освоен, начало положено, рухнула глухая стена непонимания процессов. [b] Но жажда эксперимента заставляет меня задать вопрос: какую операцию в код надо вставить, чтобы при появлении, например, на portb2 логической 1, программа глохла и колебания выключались? 1. Без кварца частота будет плыть с температурой, и весьма сильно. Вас это не смущает ? 2. Например, так: Код PORTB.0 = 0; PORTB.1 = 0; while(PINB.2 == 0) //Условие остановки генерации { //Отрабатываем первые 2 мкС #asm("nop") //Задержка на первые 2 мкС. #asm("nop") //Насколько я помню, "nop" выполняется за один машинный цикл. ... #asm("nop") //Исходя из этого рассчитайте или подберите с помощью осциллографа нужное вам кол-во "nop"ов
//Теперь отрабатываем 8 мкС PORTB.0 = 1; #asm("nop") #asm("nop") #asm("nop") ... #asm("nop")
//Теперь отрабатываем 2 мкС PORTB.0 = 0; #asm("nop") #asm("nop") ... #asm("nop")
//Теперь отрабатываем 8 мкС PORTB.1 = 1; #asm("nop") #asm("nop") #asm("nop") ... #asm("nop")
//Теперь отрабатываем 2 мкС, для чего начинаем новый виток цикла PORTB.1 = 0;
//Один цикл колебаний завершен. Выполняем новый цикл, и так продолжаем, пока не выключат питание }
//PINB.2 = 1. Останавливаем генерацию PORTB.0 = 0; PORTB.1 = 0; Книжку Крупника по Си почитайте. И мануал к CodeVision просмотрите ...
|
|
|
|
|
Nov 23 2012, 10:12
|
Группа: Новичок
Сообщений: 8
Регистрация: 23-11-12
Пользователь №: 74 525

|
Здравствуйте. У меня те-же "грабли" что и у автора, и мне очень полезна эта тема для освоения. Предыстория: На одном из англо-язычных форумах наткнулся на одну схему с описанием и "исходником" устройства на Attiny85 которое может мне помочь так как нужно портативное устройство. Автор, так-же как и я не разбирается в программировании, а в нашем городе на радио рынке Attiny нет но есть Atmega16A и Atmega8. Я пытался пере компилировать в CVAVR код но не получается Код /***************************************************** Project : Sweeper generator Version : 1.0 Date : 28/02/2012 Author : Chip type : ATtiny85 Clock freq. : 8,000000 MHz (Internal) *****************************************************/
#include <ATtiny85.h> #include <inavr.h>
// Standard defines +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define HIGH 1 #define LOW 0
#define TRUE 1 #define FALSE 0
#define ON 0 #define OFF 1
#define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80
#define MIN_FREQ 10 // 3,2Khz #define MAX_FREQ 1000 // 32Hz
// I/O Port pins ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++
#define LED_ON PORTB &= (~BIT3) #define LED_OFF PORTB |= BIT3
#define PWM_HIGH PORTB |= BIT0 #define PWM_LOW PORTB &= (~BIT0)
#define BUTTON_IN PINB & BIT4
// Global variables +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
volatile unsigned long pwm_step; volatile unsigned int pwm_counter, pwm_frequency; volatile unsigned char direction;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++ // ++ Interrupts // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++
void timer0_ovf_isr(void) __interrupt[TIMER0_OVF_vect] //error missing"{" { if (pwm_counter) { pwm_counter++; if (pwm_counter > (pwm_frequency/2)) PWM_HIGH; else PWM_LOW; if (pwm_counter >= pwm_frequency) pwm_counter=0; } }
void timer1_ovf_isr(void) __interrupt[TIMER1_OVF_vect] { if (!pwm_counter) { if (direction) { pwm_frequency++; if (pwm_frequency >= MAX_FREQ) direction=0; } else { pwm_frequency--; if (pwm_frequency <= MIN_FREQ) direction=1; }
pwm_counter=1; }
if (pwm_step) pwm_step--; }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++ // ++ Main // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++
void main(void) { // Ports initialization PORTB=0x3F; DDRB=0x09; // Timer/Counter 0 initialization TCCR0A=0x00; TCCR0B=0x01; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization PLLCSR=0x00; TCCR1=0x01; GTCCR=0x00; TCNT1=0x00; OCR1A=0x00; OCR1B=0x00; OCR1C=0x00; // External Interrupts initialization GIMSK=0x00; MCUCR=0x00; // Timers/Counters Interrupts initialization TIMSK=0x06; // Universal Serial Interface initialization USICR=0x00; // Analog Comparator initialization ACSR=0x80; ADCSRB=0x00;
// Main loop while (1) { __disable_interrupt(); LED_OFF;
while (BUTTON_IN); LED_ON; pwm_step=1832000; // 1 Min. count pwm_counter=1; // Start counter pwm_frequency=MIN_FREQ; // Min. start freq. direction=0; // Count up
__enable_interrupt();
while (pwm_step); } } Ошибка missing"{" Принцип работы такой: при подаче питания на устройство лампа (PB3) не горит устройство в режиме ожидания при нажатии кнопки (PB4) лампа загорается и с вывода (PB0) генерируется сигнал ~3.2 кГц на 1 минуту. От автора " It's designed to sweep from 32Hz to 3,2Khz for 1 minute when you press the button." Помогите пере компилировать для Atmega16A
|
|
|
|
|
Nov 23 2012, 11:43
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(20AmpMax @ Nov 23 2012, 14:12)  Помогите пере компилировать для Atmega16A Перекомпилировать не стану, а новое напишу. Если совсем по-простому, то вот: http://zalil.ru/33993241Компилятор - Codevision ... P.S. Кстати, оно и не перекомпилируется, ибо это разные МК, у них по-разному сделаны таймеры, и проч. Надо вникать, разбираться. А зачем ? Да и PWM здесь не нужна, т.к. нужна не точная частота, а "примерно 3.2 КГц" ...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|