И кстати это нормально, такая команда инвертирует соответствующий вывод порта.
может и инвертирует, только не на всех контроллерах.
FreshMan, советую почитать про битовые операции, тогда вам станет понятно что эти магические значки означают. Еще есть книга Кернегана и Ричи основателей языка си.Там тоже неплохо описано значение операторов.
Как логическое ИЛИ (а =| как раз и есть логическое или) может инвертировать значение бита? Таблица истинности: x | y | ---------- 0 | 0 | 0 0 | 1 | 1 1 | 0 | 1 1 | 1 | 1
И это не вывод в пин, а явная его установка в состояние "1". Сброс пина будет выглядеть так: PIND &= ~(1<<PIND5)
Конкретнее, пожалуйста. Поведение WinAVR'а будет независимое в данном случае от типа камня. Значит разница должна быть в апаратной реализации инструкции ORI. А эта инструкция есть часть RISC архитектуры, которая применяется (вроде) во всех мегах. Так как тогда одна и таже инструкция может по разному работать на разных камнях?
FreshMan писал(а):нужно подключить DS1307 к Atmega8 я так понимаю для данных целей задействуется аппаратный TWI
А я чет не смог дать ума аппаратному TWI, ну работало вроде, но иногда висло, лень было разбираться, легче оказалось свою программную реализацию написать..... Спойлер
#define IICDDR DDRC /*порт управления I2C*/ #define IICPORT PORTC /*порт вывода данных на линию I2C*/ #define IICPIN PINC /*порт ввода данных с линий I2C*/ #define IICData (1<<4) /*линия DATA*/ #define IICClc (1<<5) /*линия CLC*/
char ClockData [7]={};//массив данных часов: секунды, минуты, часы, день, дата, месяц, год
//####################################################################################################################### //# //# ФУНКЦИИ РАБОТЫ С ЧАСАМИ DS1307 //# //#######################################################################################################################
//ФУНКЦИЯ ЧТЕНИЯ БЛОКА ДАННЫХ ИЗ МИКРОСХЕМЫ ЧАСОВ DS1307 //чтение происходит в глобальный массив ClockData[7] //последовательность данных - [0]секунды, [1]минуты, [2]часы, [3]день, [4]дата, [5]месяц, [6]год void IICClockReadData (void) { IICStart(); IICByteWrite (0xD0);//запись данных в DS1307 IICByteWrite (0x00);//сбросить указатель адреса DS1307 на 0 IICStop();
IICStart(); IICByteWrite (0xD1);//команда на чтение данных
char* pClockData =&ClockData[0];//указатель на данные часов for (char i = 0; i<6; i++) *pClockData++= IICByteRead (0);//пишем, секунды, минуты, часы, день, дата, месяц (с выдачей подтверждением) *pClockData = IICByteRead (1);//пишем год (без подтверждения) IICStop(); }
//ФУНКЦИЯ ЗАПИСИ БЛОКА ДАННЫХ В МИКРОСХЕМУ ЧАСОВ DS1307 //запись происходит из глобального массив ClockData[7] //последовательность данных - [0]секунды, [1]минуты, [2]часы, [3]день, [4]дата, [5]месяц, [6]год void IICClockWriteData (void) { IICStart(); IICByteWrite (0xD0);//запись данных в DS1307 IICByteWrite (0x00);//сбросить указатель адреса DS1307 на 0
//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ START ПО ИНТЕРФЕЙСУ IIC void IICStart (void) { IICDDR &=~(IICData | IICClc);//единички на обеих линиях Delay2Mks();
IICDDR |= IICData;//подтяжка data к нулю Delay2Mks();
IICDDR |= IICClc;//подтяжка clc к нулю Delay2Mks(); }
//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ STOP ПО ИНТЕРФЕЙСУ IIC void IICStop (void) { IICDDR |=(IICData | IICClc);//подтяжка обеих линий к нулю Delay2Mks();
IICDDR &=~IICClc;//отпустить data Delay2Mks();
IICDDR &=~IICData;//отпустить clc Delay2Mks(); }
//ФУНКЦИЯ ЗАПИСИ БАЙТА ПО ИНТЕРФЕЙСУ IIC //АРГУМЕНТ - байт данных для вывода по IIC //ЗНАЧЕНИЕ - флаг подтверждения 0 (есть подтверждение) или 1 (нет подтверждения) char IICByteWrite (char byte) { for (char i = 0; i<8; i++) byte = IICBit (byte);
//ФУНКЦИЯ ЧТЕНИЯ БАЙТА ПО ИНТЕРФЕЙСУ IIC //АРГУМЕНТ - значение бита подтверждения (0 - есть подтверждение, 1 - нет подтверждения) //ЗНАЧЕНИЕ - принятый байт char IICByteRead (char bit) { char byte = 0xFF; for (char i = 0; i<8; i++) byte = IICBit (byte);
bit <<= 7; IICBit (bit);//передать значение бита подтверждения return byte;//возвращаем принятый байт }
//ФУНКЦИЯ ЗАПИСИ\ЧТЕНИЯ БИТА ПО ИНТЕРФЕЙСУ IIC //выводится значение старшего бита аргумента //принятый бит возвращается в младшем бите предварительно сдвинутого влево аргумента char IICBit (char byte) { if (byte & 0x80)//выводимый бит IICDDR &=~IICData;//вывод 1 на линию данных else IICDDR |= IICData;//вывод 0 на линию данных Delay2Mks();
IICDDR &=~IICClc;//старт строб импульса while (!(IICPIN & IICClc)){}//ожидание формирования строба Delay2Mks();
shads писал(а):А я чет не смог дать ума аппаратному TWI, ну работало вроде, но иногда висло, лень было разбираться, легче оказалось свою программную реализацию написать.....
В 90% случаев - правильное решение...
"Я не даю готовых решений, я заставляю думать!"(С)
Здравствуйте, уважаемые форумчане. Прошу вашей помощи. Есть программка на C, переписанная для Attiny2313, изначально предназначенная для pic16f84. Это светодиодная моргалка. Программа рассчитана на тактирование контроллера с частотой 37Кгц, на тиньке с частотой 4Мгц она работает слишком быстро, мигание светодиодов не различить. Подскажите, как её переделать, чтобы она нормально работала на 4Мгц
#include <avr/io.h>
void effect(unsigned int, unsigned char, unsigned char, unsigned char); void pause (unsigned int); void main (void) { unsigned int time, i, j; DDRB = 0xff; PORTB=0xFF; pause(900000); PORTB=0x00;
yaotzin, большое спасибо! Сейчас всё отлично работает, поставил _delay_ms(time*1);. Пришлось отключить оптимизацию в настройках компилятора gcc в Atmel Studio, hex файл получился 4.86Кб, я думал не зашьётся в тиньку 2313, но всё прекрасно прошилось
Привет всем! Пишу программу на Си для Тини2313. Это моя первая программа для АВР на Си. AVRStudio4+WinAVR. Вообщем-то при компиляции вылазят только warning'и, warning конечно не error, но я все-равно и хочу от них избавиться. Вот код (ну не все конечно, а только тот в чем проблема):
unsigned char hextobcd(sec) //Функция, вот sec в скобках правильно указано? //Не надо ведь писать unsigned char sec? sec ведь это глобальная переменная { sec++; return; }
int main(void) { hextobcd(sec); while(1); }
Значит warning такой: type of 'sec' defaults to 'int'. Это он предлагает поменять тип переменной sec на int? Зачем? Зачем сжирать в двое больше оперативки?