andreichk
Jan 25 2008, 21:00
Привет народ.Вот решил я слепить себе нечто из указанных в теме компонентов.Нарисовал и изготовил макетку, красиво всё распаял и написал из надёрганных в сети кусков маленькую програмку для управления ЖКИ. Вначале, после нудного изучения даташитов никак не мог инициализировать ЖКИ, но потом разобрался что к чему и наконец он начал подавать признаки жизни и засветился.
Компилятор, который я пользую - CCS, имеет в своём составе файл SED1335.C , но как я не пытался приспособить его, так и не смог.Порывшись в сети,я нашёл другой файл с таким же названием, но вроде бы не для ПИКов, а для чего-то другого.Однако , слегка подшаманив его, я смог встроить его в прогу и он заставил таки выдавать на экран символы в текстовом режиме(даже с возможностью размещения в заданое место) и переключаться в графический режим.
И на этом всё и закончилось.
Все попытки нарисовать линию или круг или просто точку,несмотря на множество примеров, я так и не смог. Позаимствовав из старого файла процедуру
void glcd_pixel(int16 x, int16 y, int1 color)
{
int8 data;
int16 addr;
// Calculate the byte address containing the pixel
addr = GLCD_GRAPHICS_ADDR + (GLCD_WIDTH/8 * y + x/8);
// Read the byte of data at the address
data = getData(addr);
// Turn the pixel on or off
if(color == ON)
bit_set(data, 7 - x%8);
else
bit_clear(data, 7 - x%8);
// Write the new data byte to display memory
setData(addr, data);
}
я попробовал нарисовать на экране пиксель, но он вроде как нарисовался но разместился не в тех координатах, которые я указывал.Как я понимаю, за размещение отвечает строка
//GLCD_GRAPHICS_ADDR- нач. адрес- 1200, GLCD_WIDTH- кол во символов в строке- 320
addr = GLCD_GRAPHICS_ADDR + (GLCD_WIDTH/8 * y + x/8);
Может кто из вас раскомментирует эту странную формулу и подправит её, если она неправильная.
andreichk
Jan 27 2008, 04:06
Ура !!! Заработало !!! Подправил биты инициализации.Умею нарисовать кружёчки и линии. И даже примитивный осциллограф получился.Берёт сигнал с АЦП1, а АЦП0 как развёртка, получается хреновенько, но как сказал известный демократ- ПРОЦЕСС ПОШЁЛ. Теперь надо научиться выводить параметры и картинки.Может кто подскажет , куды кинуться?
arizona
Jan 28 2008, 07:38
Цитата(andreichk @ Jan 27 2008, 07:06)

Теперь надо научиться выводить параметры и картинки.Может кто подскажет , куды кинуться?
посмотри микрочиповскую реализацию
www.microchip.com/graphics
и немного по-русски
http://microchip.com.ru/1010/Support/GUI.html
andreichk
Jan 28 2008, 18:26
Цитата(arizona @ Jan 28 2008, 08:38)

посмотри микрочиповскую реализацию
www.microchip.com/graphics
и немного по-русски
http://microchip.com.ru/1010/Support/GUI.htmlСпасибо, будем поглядеть
andreichk
Jan 29 2008, 22:32
Сегодня закончил оформление внешнего вида. Нарисовал сетку размером 320х240, но она вся не влезла, очевидно из-за каких-то ограничений.Пришлось поделить её на две части и с помошью процедуры перевёртыша загрузить два раза.Благодаря двухслойной функции экрана сетка не затирается.Так же нарисовал несколько маленьких картинок и подгрузил их для красявости.
Ниже привожу текст процедуры и фото
void bild(unsigned int16 addr,unsigned char data)
{
send_msg( 0x46, 1, 0, 1, 0 );
Output_bit(LCD_A0 ,0);
write_data( (addr) & 0x00ff );
write_data( (addr)>>8 & 0x00ff );
send_msg( 0x42, 1, 0, 1, 0 );//
Output_bit(LCD_A0 ,0);
Output_d(data);
Output_bit(LCD_CS,0);//
Output_bit(LCD_WR,0); //
Output_bit(LCD_WR,1);//
Output_bit(LCD_CS,1);//
}
void DrawImage(unsigned int16 y1,unsigned int16 y2 )// нормальный вид
{
unsigned int16 addr, x,y,i;i=0;
for (y = y1; y < y2; y++)
{
for (x = 0; x < 264;x=x+8)
{
addr = 40 * y + x/8 - 1 ;//10802;//расчитать байт адреса, содержащего пиксель
bild( addr,Grid_8x4[i++]);// работает
}
}
}//--------------------------OK
//#####################################################################
void DrawImage11(unsigned int16 y1,unsigned int16 y2 )// перевёртыш
{
unsigned int16 addr, x,y,i;i=3959;
for (y = y1; y < y2; y++)//
{
for (x = 264; x > 0;x=x-8)
{
addr = 40 * y + x/8 - 2 ;//10802;//расчитать байт адреса, содержащего пиксель
bild( addr,Grid_8x4[i--]);// работает
}
}
}//--------------------------OK
//#####################################################################
andreichk
Jan 31 2008, 19:18
Хочу попробовать перенести все картинки в последовательную память с I2C-BUS протоколом, а то они много места в процессоре занимают.
Цитата(andreichk @ Jan 30 2008, 02:32)

Сегодня закончил оформление внешнего вида. Нарисовал сетку размером 320х240, но она вся не влезла, очевидно из-за каких-то ограничений.Пришлось поделить её на две части и с помошью процедуры перевёртыша загрузить два раза.Благодаря двухслойной функции экрана сетка не затирается.Так же нарисовал несколько маленьких картинок и подгрузил их для красявости.
Ниже привожу текст процедуры и фото
Код
//#####################################################################
void DrawImage11(unsigned int16 y1,unsigned int16 y2 )// перевёртыш
{
unsigned int16 addr, x,y,i;i=3959;
for (y = y1; y < y2; y++)//
{
for (x = 264; x > 0;x=x-8)
{
addr = 40 * y + x/8 - 2;//10802;//расчитать байт адреса, содержащего пиксель
bild( addr,Grid_8x4[i--]);// работает
}
}
}//--------------------------OK
//#####################################################################
Не вдаваясь в подробности, просто по оформлению, используй теги под символом #.
Если кто смотреть будет, так читать легче.
andreichk
Feb 4 2008, 23:07
Слепил сегодня процедурку рисования кривых.Теперь вот голову ломаю . как это всё синхронизировать, чтобы картинка устойчивой была.Подскажите плиз
//#####################################################################
void front(unsigned int8 x,unsigned int8 y_anf,unsigned int8 y_end)
{unsigned int8 y;
for (y = y_anf ; y > y_end; y--)
{
pixel(x,y,1);
}
}//--------------------------OK
//#####################################################################
void spad(unsigned int8 x,unsigned int8 y_anf,unsigned int8 y_end)
{unsigned int8 y;
for ( y = y_anf ; y < y_end ; y++ )
{
pixel(x,y,1);
}
}//--------------------------OK
//#####################################################################
void pix(unsigned int8 y_pos)// рисуем кривую, типа синусоиды и пр.
{unsigned int8 x , y , yy ; x = 1; y = 0; yy = 0;
for(;;){
x++;
if (x==255) {x=1;setCursorAddress(0x2581);clear_graphic();}
delay_ms(Zeitablenkung_x(0)); //развёртка Sec/Div
yy=y;
y = input_b()+y_pos;
// y = Amplitude_y(1) + y_pos-150;
if (yy>y) front(x,yy,y); // Рисуем фронт
if (yy<y) spad(x,yy,y); // Рисуем спад
pixel(x,y,1);// Рисуем вершину
}
}//--------------------------OK
//#####################################################################
Вот готовый видеоконтроллер для управления ЖКИ на базе SED1335:
http://www.telesys.ru/electronics/projects.php?do=p148
andreichk
Feb 7 2008, 16:40
вы мне его уже предлагали, только за деньги я и сам купить умею.
Коммерческие предложения меня не интересуют, так что спасибо.... не надо
А почему у вас экран малинового цвета, это пленка наклеена или подсветку поменяли?
Для рисования рекомендую посмотреть библиотечку uc/GUI, драйвер для этого контроллера там уже есть, возможностей у нее много, а самое главное - хоть как-то систематизируется подход. В будущем сможете безболезненно поменять один дисплей на другой с расширением количества цветов например.
andreichk
Feb 8 2008, 09:31
да цвет любой можно сотворить- плёночку цветную под экран сунул и всё.А вообще он ЧБ.
Насчёт uc/GUI не нашёл ничего.У меня поисковик только на какие-то китайские сайты выводит, ничего не понятно.Может ссылочку кините.Спасибо заранее
китайские сайты нормально читаются через
http://babelfish.altavista.com/ язык - chinese-simp. там и ссылки есть. можно также с электроникса скачать, но надо быть "своим".
andreichk
Feb 10 2008, 17:41
Выяснил причину по которой HEX-файл неполностью зашивался в процессор. Оказывается программа прошивки IC-Prog1.6А програмирует только до адреса 0х1000.Дальше сплошные FFFF.
Выкинул её нафик.Теперь програмирую другой прогой - P18 Parallelportbrenner V1.8 , взятой с сайта
http://www.sprut.de.
По ходу научился выводить тексты в графическом режиме и переменные величины.
//########## выводим на экран числа в графическом режиме ##################
void displayVoltage(int wert) {
char voltage[9];
sprintf(voltage, "%f",(float)(1.715*(5.00 - wert * .01960784))); // преобразуем в текст
voltage[4] = '\0'; //ограничиваем тремя знаками
rect(5, 230, 29, 237, 1,0); //стираем старое значение
text57(5, 230, voltage, 1, 1); //выводим новое значение
}//--------------------------OK
//####################################################
andreichk
Feb 11 2008, 22:39
частота 88 Гц, амплитуда 2.15 вольт
andreichk
Feb 17 2008, 22:31
Попытки записи массива типа
const byte mS_uS[] = {
0,0,0,0,0,
0,7,128,1,224,
0,8,64,2,16,
61,200,1,10,0,
34,40,1,10,0,
34,39,129,9,224,
34,32,65,8,16,
34,32,65,8,16,
34,40,65,26,16,
34,39,129,233,224,
0,0,1,0,0,
0,0,1,0,0,
}; не увенчались успехом
Написал процедуру
void EEPROM_WRITE(long int address)
{unsigned int16 i;
for (i=0;i<60;i++)
{
write_ext_eeprom(address, mS_uS[i]);
}break;
}//--------------------------во-первых пишет целых 5 минут
во-вторых нифига не читает с помошью процедуры
long int EEPROM_READ(long int addr)
{long int dat;
for (addr=0;addr<990;addr++)
{
dat = read_ext_eeprom(addr);
}return dat;
}//--------------------------
//#####################################################################
void Grid_UpXXX(unsigned int16 y1,unsigned int16 y2,unsigned char setka )//
{unsigned int16 addr, x,y,i;i=0;
for (y = y1; y < y2; y++)
{
for (x = 0; x < 264;x=x+8)
{
addr = 40 * y + x/8 ;//расчитать байт адреса, содержащего пиксель
if( setka==1 ) bild( addr,EEPROM_READ(0));// крупная сетка
else bild( addr,EEPROM_READ(1));// мелкая сетка
}
}
}//-------- Подскажите где я напортачил
andreichk
Feb 20 2008, 17:50
да, не густо тут помошников.....
andreichk
Feb 20 2008, 23:20
ещё одно фото для истории.
двухканальный вариант,построенный на ADS831 и FIFO IDT7201 .Всем этим хозяйством управляет PLCD XILINX XC9572.
Cинус , частота- 20 кГц.Каждый канал имеет свой переключатель развёртки.Почему-то рисует половинкой
andreichk
Feb 23 2008, 15:32
проблема рисования синусоиды половинками решена добавлением резистора 47к на неинвертирующий вход входного ОУ.Осталось добиться устойчивой синхронизации и максимально возможной частоты сигнала.
Первая попытка наблюдения видеосигнала с камеры(сверху)
и одновременный синус 20 кГц(снизу)
Ну хоть кто-нибудь порадуется вместе со мной
andreichk
Feb 25 2008, 22:22
Ура !!! Удалось засинхронизироать картинку
//#####################################################################
void pix_A(unsigned int8 y_pos_A,unsigned int8 offset)// рисуем кривую, типа синусоиды и пр.
{unsigned int8 x, y , yy ;//
unsigned int16 xx;
y = y_pos_A;
Output_bit(PLCD_FIFO_RES ,0);//PIN_C0// сброс FIFO в "0"
Output_bit(PLCD_FIFO_RES ,1);//PIN_C0// и разрешение на считывание
Output_bit(READ_FIFO_B ,1); //PIN_C1 запрет канала B
do{ // слабая попытка синхронизации
Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1);//PIN_C2
}while(input_b()== adcA );//уже лучше,но всё равно плохо
//--------------- предварительная запись в буфер ---------------------
for(xx=0;xx<512;xx++){// канал A
Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить
adcA=input_b();
adcA = (adcA > offset) ? offset : adcA;//ограничитель до 115
adcA = 255 - adcA;
Buff_[xx] = adcA;//записываемся в буфер 512 раз
Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить
} xx=0;
for(;;) {//синхронизация буфера по фронту или по спаду
if( Buff_[xx++] <= 175) break; //по фронту
// if( Buff_[xx++] >= 175) break; //по спаду
}
sbros(adcA);
wert_A(adcA);
if( xx >= 255 ) xx = xx - 255; //приводим к int8
//--------------- собственно кривая ---------------------------
for(x=1;x<255;x++){
yy = y;
y = Buff_[xx++] + y_pos_A;
if (yy>y) front(x,yy,y); // Рисуем фронт A
if (yy<y) spad(x,yy,y); // Рисуем спад A
adcA=y-y_pos_A;
pixel(x,y,1); // Рисуем вершину A
}
}//--------------------------OK
//####################################################################
Ilya_A
Feb 26 2008, 07:52
Поздравляю, картинка, конечно красивая, но меня волнует следующий вопрос:
Насколько я помню, при рисовании динамически изменяющихся картинок на SED1335 должны возникать флики на экране. Как у вас обстоят дела, с такими глюками?
andreichk
Feb 26 2008, 17:54
Цитата(Илья @ Feb 26 2008, 08:52)

Поздравляю, картинка, конечно красивая, но меня волнует следующий вопрос:
Насколько я помню, при рисовании динамически изменяющихся картинок на SED1335 должны возникать флики на экране. Как у вас обстоят дела, с такими глюками?
Если флики - это когда в разных кадрах есть места по-разному освещенные, то на тёмном фоне их практически не видно, линии-то тонкие и все эти мелькания происходят как бы за экраном, так что с фликами пока всё ОК.
andreichk
Feb 27 2008, 14:29
У меня сегодня день рождения. Спасибо всем за поздравления
andreichk
Feb 27 2008, 20:02
сегодня попробовал подать на вход меандр от кварцевого генератора.Нармально можно рассмотреть частоту в 1 МГц при тактовой частоте ПИКа и FIFO- 40МГц. Но вот незадача- не совпадает меандр с масштабом клеток- получается примерно полторы клетки на 1МГц. Перерисовывать клетки как-то не очень хочется, значит надо подгонять частоту тактирования.Можно ли это сделать программно в ПЛИСе или нет-кто мне подскажет?
andreichk
Mar 2 2008, 13:44
Прошу помощи по теме
Дело такое, надо мне от шифратора кнопок , кот. я зашил в ПЛИСе передать в ПИК значение нажатой кнопки.То есть , если нажата кнопка 1, то вылетает один импульс, если 2, то два импульса и т.д. до 15ти.Длительность импульса прим. 0.5мс без паузы , то есть весь пакет примерно от 0.5 + пауза 0.5мс, до 30ти.Импульсы подаются на вход РА4.также смоделирован признак нажатия кнопки, то есть высокий уровень на весь размер пакета, он подается на порт РА5. Я нарисовал вот такую процедурку, но она почему-то не работает как надо.Может такой способ опознавания вообще не катит?
//###### ШИФРАТОР КНОПОК УПРАВЛЕНИЯ. ПОРТ А НА ВХОД ########################
#ifndef Code_Out
#define Code_Out PIN_A4// Пакеты импульсов от 1 до 15
#endif
//--------------------------
#ifndef TASTE_EN
#define TASTE_EN PIN_A5//Признак нажатия кнопки- лог.1
#endif
//###############################
void Tasten(void)// ОПРОС КНОПОК
{unsigned int8 puls;
if (input(TASTE_EN))//признак нажатия кнопки лог."1"
{
while(!input(TASTE_EN));//ждём спад обрезанного импульса
rect(265, 80, 269, 86, 1,0);
text57(265,80,u ,1,1);
puls=0;
while(!input(Code_Out));//ждём спад
while(input(TASTE_EN))//начинаем отсчёт по фронту
{
while(input(Code_Out));//ждём фронт
while(!input(Code_Out));//ждём спад
wert_A(puls++);
}
puls=0;
delay_ms(200);
}
else{
rect(265, 80, 269, 86, 1,0);
text57(265,80,m ,1,1);
}
}
//###########################################################################
void wert_A(unsigned int8 wert)
{
char voltage[9];
sprintf(voltage, "%u",(unsigned int8)( wert)); // преобразуем в текст
//voltage[4] = '\0'; //ограничиваем тремя знаками
rect(150, 230, 175, 237, 1,0); //стираем старое значение
text57(150, 230, voltage, 1, 1); //выводим новое значение
}//--------------------------OK
//######################################################################
Насколько я понимаю нужно дождаться перехода из низкого в высокий уровень на RA5, а затем посчитать количество импульсов на RA4.
Следовательно нужно сделать так:
Код
unsigned int8 GetButton(void){
unsigned int8 puls;
while(input(TASTE_EN)); // если зашли уже в момент передачи кода кнопки то дождаться окончания передачи
puls=0;
while(!input(TASTE_EN));//дождаться начала следующей передачи кода кнопки
while(input(TASTE_EN)){//пока активно RA5
while(!input(Code_Out)){//ждём фронт
if (!input(TASTE_EN)) return puls;//проверяем: если передача законилась то выйти, чтобы не зависнуть
}
while(input(Code_Out));//ждём спад
puls++;
}
return puls;
}
А вообще зачем такие сложности, не проще ли сделать так: Передача кода кнопки только по одной ноге, а кодирование длительностью ипульса, например:
0.5 мс - кнопка №1
1 мс - кнопка №2
1.5 мс - кнопка №3
и т.д.
тогда для дешифровки делаем следующим образом:
настраиваем прерывание по фронту.
в обработчике прерывания стартуем таймер, и ждем в цикле спада. Стопорим таймер и смотрим: сколько натикало - такой и код
andreichk
Mar 3 2008, 14:34
Спасибо, я попробую как вы советуете и отпишусь
andreichk
Mar 3 2008, 15:57
попробовал предложенный код.Он работает,только не совсем так.А именно- теперь осциллограмма появляется только в момент нажатия любой кнопки, а иначе картинка замирает.Значение кнопки отображается не совсем корректно- или 0 или на одно значение меньше или правильное значение.
Наверное нужно уточнять частоту импульсов и настраивать прерывание по нажатию- изменению состояния RA5 ? Только я не знаю как(ещё не изучал этот вопрос).Если укажете правильный путь- буду благодарен
andreichk
Mar 3 2008, 21:44
код работает с небольшой доделкой и понижением частоты импульсов опроса кнопок до 150 кГц.
думаю, что этим можно и ограничиться
unsigned int8 GetButton(void){
unsigned int8 puls;
if (!input(TASTE_EN)) return ;//если кнопка не нажималась- уходим
while(input(TASTE_EN)); // если зашли уже в момент передачи кода кнопки то дождаться окончания передачи
puls=0;
while(!input(TASTE_EN));//дождаться начала следующей передачи кода кнопки
while(input(TASTE_EN))//пока активно RA5
{
while(!input(Code_Out))//ждём фронт
{
if (!input(TASTE_EN)) return puls;//проверяем: если передача законилась то выйти, чтобы не зависнуть
}
while(input(Code_Out));//ждём спад
puls++;
}
return puls;
}...................................................................
а вызов делаем так и уходим от нуля
x=GetButton();
if(x>0) wert_A(x);
andreichk
Mar 4 2008, 18:56
вот такое у меня ещё пожелание(чувствую, что без посторонней помощи не обойдусь) касательно кнопок управления.
каждый раз ,при нажатии кнопки со значением переменной puls==12, нужно, чтобы значение другой переменной (хх напр.)однократно увеличивалось на единицу и оставалось таким, а при нажатии кнопки со значением puls==13 уменьшалось на единицу и оставалось таким. Я сам пробовал,фигня у меня получается-если держать кнопку и не отпускать, то хх всё время увеличивается или соотв. уменьшается, а это недопустимо.Если с этим поможете, то тогда влпрос с управлением будет закрыт.Спасибо заранее
Ilya_A
Mar 11 2008, 02:50
Извиняюсь за задержку с ответом - праздники, даже не заходил на форум

Решить вашу проблему можно, заведя переменную для хранения значения предыдущей нажатой кнопки, следующим образом:
Код
unsigned char XX; // переменная которая будет изменяться
unsigned char key=0,keyold=0;
key=GetButton();
if(key==12){
if(keyold!=12) XX++;
}else if(key==13){
if(keyold!=13) XX--;
}
keyold=key;
Transon
Mar 12 2008, 13:18
Это самая лучшая разработка одного человека какую я видел за последнее время.
Я сам пытался разработать цифровой осциллограф, но так до конца не доделал, АЦП не заработал (AD9283 100Msps), сделал его только как логический анализатор через LPT порт с частотой дискретизации 48MHz и 8 каналов, потом забросил, щас снова интерес появился, я хочу повторить ваш осциллограф для себя.
Аналогов такого осциллографа со схемами я не нашёл.
andreichk
Mar 13 2008, 19:02
Спасибо всем ответившим и помогающим.Не надо извиняться, все мы ведь понимаем , что кроме и-нета у каждого есть ещё и личная жизнь, работа и многое другое, так что всё нормально, спасибо, что отозвались.
andreichk
Mar 13 2008, 20:26
Код
unsigned char XX; // переменная которая будет изменяться
unsigned char key=0,keyold=0;
key=GetButton();
if(key==12){
if(keyold!=12) XX++;
}else if(key==13){
if(keyold!=13) XX--;
}
keyold=key;
тут не совсем так как надо получается, а именно- значение переменной ХХ меняется только один раз, при повторном нажатии на ту же кнопку оно уже не меняется. А нужно , чтобы оно увеличивалось(или уменьшалось) на единицу при каждом нажатии.
Ilya_A
Mar 14 2008, 10:41
Цитата(andreichk @ Mar 14 2008, 04:26)

Код
unsigned char XX; // переменная которая будет изменяться
unsigned char key=0,keyold=0;
key=GetButton();
if(key==12){
if(keyold!=12) XX++;
}else if(key==13){
if(keyold!=13) XX--;
}
keyold=key;
тут не совсем так как надо получается, а именно- значение переменной ХХ меняется только один раз, при повторном нажатии на ту же кнопку оно уже не меняется. А нужно , чтобы оно увеличивалось(или уменьшалось) на единицу при каждом нажатии.
Почему же? Все будет ОК если функция GetButton() будет возвращать 0 если не получила никакого кода клавиши. Тогда переменная keyold занулится (в момент отжатия) и при следующем нажатии на ту же кнопку произойдет необходимая операция
andreichk
Mar 15 2008, 10:12
дело в том , что момент отжатия невозможно установить точно, так как он происходит в произвольный момент времени и там ведь ещё целая куча задач выполняется.Плохо то, что я не могу назначить прерывание по изменению состояния порта РА5,в компиляторе такого почему-то не прописано(может его вобще не существует для ПИКа 18Ф4550), хотя в общей доке для компилятора описание имеется.Плёхо, очень плёхо......
Ilya_A
Mar 15 2008, 12:14
Цитата(andreichk @ Mar 15 2008, 18:12)

дело в том , что момент отжатия невозможно установить точно, так как он происходит в произвольный момент времени и там ведь ещё целая куча задач выполняется.Плохо то, что я не могу назначить прерывание по изменению состояния порта РА5,в компиляторе такого почему-то не прописано(может его вобще не существует для ПИКа 18Ф4550), хотя в общей доке для компилятора описание имеется.Плёхо, очень плёхо......
Есть 2 выхода:
Во первых можно перекинуть с RA5 на одну из ног: RB0, RB1, RB2 - ноги на которых можно настроить прерывания по фронту или по спаду.
Либо можно завести внутренний таймер, с периодом переполнения, например 100 мс и настроить прерывание, по переполнению. А уже в прерывании выполнять GetButton(). - появиться гарантированное время между опросами клавы.
andreichk
Mar 15 2008, 12:50
перекидывать ножки на порт РВ как-то не очень хочется, так как с него читаются данные(вдруг какие-нибудь баги полезут и картинка начнёт портиться.А вот второй вариант наверное подойдёт, только вот с прерываниями у меня сложности.....
вот перечень прерываний.какие мои дальнейшие действия?
////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
// CLEAR_INTERRUPT(), INTERRUPT_ACTIVE(),
// EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H 0x40
#define H_TO_L 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL 0xF2C0
#define INT_RTCC 0xF220
#define INT_TIMER0 0xF220
#define INT_TIMER1 0x9D01
#define INT_TIMER2 0x9D02
#define INT_TIMER3 0xA002
#define INT_EXT 0xF210
#define INT_EXT1 0xF008
#define INT_EXT2 0xF010
#define INT_RB 0xFFF208
#define INT_AD 0x9D40
#define INT_RDA 0x9D20
#define INT_TBE 0x9D10
#define INT_SSP 0x9D08
#define INT_CCP1 0x9D04
#define INT_CCP2 0xA001
#define INT_BUSCOL 0xA008
#define INT_LOWVOLT 0xA004
#define INT_COMP 0xA040
#define INT_EEPROM 0xA010
#define INT_OSCF 0xA080
#define INT_SPP 0x9D80
#define INT_USB 0xA020
#list
Ilya_A
Mar 15 2008, 17:18
Так... насколько я понял компилятор у вас CCS - я с ним не знаком (дружу в основном с C18, PICC18)
Ну ничего, бум думать, где-то он у меня валялся...
Хреново что реализация прерываний сильно зависит от компилятора, но постараюсь помочь хотябы идеологически)
Тактовая частота, насколько я понял - 40 МГц (т.е. 10 MIPS) ?
Для начала ссобщите какие остались свободные таймера и использовали ли вы CCP модули?
Да, и еще, используется ли у вас в программе на данный момент уже хоть одно прерывание?
И на последок - какая сейчас используется длина импульса кодировки. Насколько я понял вы идеологию кодировки не поменяли?
andreichk
Mar 15 2008, 18:53
частота 40 МГц.
ни один из трёх таймеров не задействован, прерывания тоже.
ССР также отключены.
длительность импульса 4мкс, между импульсами тоже 4 мкс
идеология не поменялась, хотя меня долго кто-то уговаривал,но я не поддался.....
Ilya_A
Mar 16 2008, 07:27
Хорошо. Теперь приступим:
Возьмем за базу TMR0, у него большой прескалер (на 10 MIPS можно получить до 1.6 с.)
Код
.....
//Гдето в инициализации программы
в T0CON указываем:
as 16 bit timer/counter
Internal instruction cycle clock
TMR0 prescaler is assigned
Prescaler выбираем из следующих соображений:
1:8 - 0.0524288 с
1:16 - 0.1048576 с
можно и другие варианты, достаточное значение опредилится опытным путем
TMR0H=0; // Зануляем таймер
TMR0L=0;
TMR0IF=0; //Очищаем флаг
TMR0IE=1; //Включаем прерывание по переполнению
IPEN=0; //Отключаем приоритет прерываний
PEIE=1; //Включаем прерывания перефирии
GIE=1; //Включаем глобальный флаг разрешения прерываний
TMR0ON=1; //Затем стартуем таймер:
.....
Почитал я немного про CSS, походу там обработка прерываний делается так:
(для экономии времени на вызов функции лучше тело GetButton перенести сюда, также нужно сделать глобальными переменные key и keyold)
Код
...
где- то в программе:
int8 key=0,keyold=0; // незнаю, как в CCS но в PICC18 я бы добавил ключевое слово volatile
...
//Непосредственно обработчик прерываний
#int_timer0
void timer0_isr(void){
TMR0IF=0;// Очистим флаг прерывания
key=0;
if (!input(TASTE_EN)){//теперь, раз уж мы сюда зашли, придется дождаться начала передачи кода клавиши
while(!input(TASTE_EN));
}else{// а если зашли уже в момент передачи кода кнопки то придеться дождаться окончания передачи...
while(input(TASTE_EN));
while(!input(TASTE_EN));//а также ждем начало следующей передачи
}
while(input(TASTE_EN))//пока активно RA5
{
while(!input(Code_Out))//ждём фронт
{
if (!input(TASTE_EN)) break;//проверяем: если передача законилась то выходим
}
if (!input(TASTE_EN)) break;//проверяем: если передача законилась то выходим
while(input(Code_Out));//ждём спад
key++;
}
//по хорошему эту обработку тоже нужно занести сюда:
if(key==12){
if(keyold!=12) XX++; //XX тоже должна быть глобальной
}else if(key==13){
if(keyold!=13) XX--;
}
keyold=key;
}
...
А уже в теле программы можно спокойно, в любой момент, проверять переменную key....
В особо критичных моментах можно будет на время выключать прерывания, например:
Код
GIE=0;
бла, бла,бла....
GIE=1;
Да, и еще - не совсем понял как кодируется "не нажата ни одна клавиша" - по хорошему, нужно чтобы был импульс на TASTE_EN, без импульса на Code_Out
andreichk
Mar 16 2008, 11:15
компилятор не хочет это признавать
TMR0IF=0;// Очистим флаг прерывания
Ilya_A
Mar 16 2008, 12:55
Цитата(andreichk @ Mar 16 2008, 19:15)

компилятор не хочет это признавать
TMR0IF=0;// Очистим флаг прерывания
Значит этот бит либо не прописан, либо прописан каким либо другим образом.
Вообще-то этот бит принадлежит регистру INTCON.
Можно попробывать варианты: INTCON.TMR0IF=0 или INTCONbits.TMR0IF=0.
Ну вообще-то вам лучше знать как обращаться к битам регистров в вашем компиляторе.

На крайняк такой вариант точно проканает: INTCON&=0b11111011;
andreichk
Mar 16 2008, 14:49
пробую так его прописать
set_timer0(0); // TMR0IF=0;// Очистим флаг прерывания
тоже не катит INTCON&=0b11111011;
вообще это идиотизм, что эти компиляторописатели подменяют стандартные описания какими-то собственновыдуманными конструкциями, поди разбери, что чем заменяется.
Вот что я решил, у меня тут с ПЛИСкой проблемы, вернее с обьеденением некоторых функций, которые я в ней заложил.Поэтому я решил инициализировать ещё 4 пина и напрямую ввести их в ПИК на порты РА0,РА1,РА2,РА3(они у меня ничем не заняты).И тогда я смогу простым нажатием на соотв.кнопку увеличивать-уменьшать значение переменной ХХ.Прошу пока все дальнейие изыскания на эту тему приостановить, сделать паузу и попить пивка напр.
Ilya_A
Mar 16 2008, 16:00
Ну ладно, удачи, все способы полезны - главное, чтобы цель была достигнута.

П.С. Единственный плюс, помоему, этого CCS - в том, что в нем написана куча библиотек для периферии. А так, IMHO не серьезный компилятор. 8)
andreichk
Mar 16 2008, 20:14
вот такой вид приняла означенная процедура опроса кнопок.теперь все кнопки вызывают правильные команды и выдаютправильные значения на ЖКИ
Цитата
//######################################################################
//Непосредственно обработчик прерываний
#int_timer0
void timer0_isr(void){
set_timer0(0); // TMR0IF=0;// Очистим флаг прерывания
//...... Этими кнопками изменяем показания SEC/DIV Канал А ....
if (input(OUT_A_UP))
{
while(input(OUT_A_UP));XX++;
}
else if (input(OUT_A_DOWN))
{
while(input(OUT_A_DOWN));XX--;
}
if(XX>8) XX=1;
if(XX<1) XX=8; //ограничиваем ХХ от 1 до 8
//.................Другие кнопки........................
key=0;
if (!input(TASTE_EN)) return ;//если кнопка не нажата - уходим
while(input(TASTE_EN));
while(!input(TASTE_EN));//а также ждем начало следующей передачи
while(input(TASTE_EN))//пока активно RA5
{
while(!input(Code_Out))//ждём фронт
{
if (!input(TASTE_EN)) break;//проверяем: если передача закончилась то выходим
}
if (!input(TASTE_EN)) break;//проверяем: если передача закончилась то выходим
while(input(Code_Out));//ждём спад
key++;
}
} //--------------------------OK
//######################################################################
Спасибо за оказанную помощь .
Илье особый

и уважуха
andreichk
Mar 19 2008, 20:46
Чего-то ни одной умной мысли не лезет в голову, наверное пора отпуск брать.
Решил пока привести пример написания процедуры рисования кривой на экране.Покритикуйте плиз, может что-нить улучшить можно.
Цитата
//############### Рисуем фронт #################################
void front(unsigned int8 x,unsigned int8 y_anf,unsigned int8 y_end)
{unsigned int8 y;
for (y = y_anf ; y > y_end; y--)
{
pixel(x,y,1);
}
} //--------------------------OK
//################ Рисуем спад #####################################
void spad(unsigned int8 x,unsigned int8 y_anf,unsigned int8 y_end)
{unsigned int8 y;
for ( y = y_anf ; y < y_end ; y++ )
{
pixel(x,y,1);
}
} //--------------------------OK
//#####################################################################
void pix_A(unsigned int8 y_pos_A) // рисуем кривую, типа синусоиды и пр.
{unsigned int8 x, y , yy ;//
unsigned int16 xx;
Output_bit(PLCD_FIFO_RES ,0); //PIN_C0// сброс FIFO в "0"
Output_bit(PLCD_FIFO_RES ,1); //PIN_C0// и разрешение на считывание
Output_bit(READ_FIFO_B ,1); //PIN_C1 запрет канала B
// слабая попытка синхронизации
do{ Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1);//PIN_C2
}while( adcA == 0);
do{ // ещё одна попытка синхронизации
Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1); //PIN_C2
}while(input_b()== adcA ); //уже лучше,но всё равно плохо
//--------------- предварительная запись в буфер ---------------------
for(xx=0;xx<1024;xx++){ // канал A
Output_bit(READ_FIFO_A ,0); //PIN_C2. разрешить
adcA=input_b(); //чтение порта В
adcA = (adcA > 200) ? 200 : adcA; //ограничитель до выбранной величины
adcA = 255 - adcA; // разворот на 180° по вертикали
Buff_[xx] = adcA; //записываемся в буфер
Output_bit(READ_FIFO_A ,1); //PIN_C2.запретить
} xx=0;
switch(syncA){ //синхронизация буфера по фронту или по спаду
case 1 :while( Buff_[xx++] > sync_volume_A);break; //по фронту
case 2 :while( Buff_[xx++] <= sync_volume_A+115);break; //по спаду
}
//значительно лучше в совокупности с двумя предыдущими
if( xx >= 255 ) xx = xx - 255; //приводим к int8
//--------------- собственно кривая ---------------------------
for(x=1;x<255;x++){
yy = y;
y = Buff_[xx++] + y_pos_A;
if (yy>y) front(x,yy,y); // Рисуем фронт A
if (yy<y) spad(x,yy,y); // Рисуем спад A
adcA=y-y_pos_A;
pixel(x,y,1); // Рисуем вершину A
}
} //--------------------------OK
//####################################################################
Ilya_A
Mar 20 2008, 03:56
Цитата(andreichk @ Mar 20 2008, 04:46)

Чего-то ни одной умной мысли не лезет в голову, наверное пора отпуск брать.
Решил пока привести пример написания процедуры рисования кривой на экране.Покритикуйте плиз, может что-нить улучшить можно.
Что касаемо улучшения - то в первую очередь нужно оптимизировать самые "тормозные места" - и в первую очередь это циклы.
Я бы процедуру отрисовки переписал иначе:
Код
void pix_A(unsigned int8 y_pos_A) // рисуем кривую, типа синусоиды и пр.
{ unsigned int8 x, y , yy;
Output_bit(PLCD_FIFO_RES ,0); //PIN_C0// сброс FIFO в "0"
Output_bit(PLCD_FIFO_RES ,1); //PIN_C0// и разрешение на считывание
Output_bit(READ_FIFO_B ,1); //PIN_C1 запрет канала B
// слабая попытка синхронизации
do{ Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1);//PIN_C2
}while( adcA == 0);
do{ // ещё одна попытка синхронизации
Output_bit(READ_FIFO_A ,0);//PIN_C2
adcA=input_b();
Output_bit(READ_FIFO_A ,1); //PIN_C2
}while(input_b()== adcA ); //уже лучше,но всё равно плохо
//-------------------- синхронизация ---------------------------
while(1){
Output_bit(READ_FIFO_A ,0); //PIN_C2. разрешить
adcA=input_b(); //чтение порта В
Output_bit(READ_FIFO_A ,1); //PIN_C2.запретить
adcA = (adcA > 200) ? 200 : adcA; //ограничитель до выбранной величины
adcA = 255 - adcA; // разворот на 180° по вертикали
if (syncA==1){
if(adcA>sync_volume_A) continue;
else break;
}else if (syncA==2){
if(adcA<=sync_volume_A+115) continue;
else break;
}
}
//--------------- собственно кривая ---------------------------
for(x=1;x<255;x++){
yy = y;
Output_bit(READ_FIFO_A ,0); //PIN_C2. разрешить
adcA=input_b(); //чтение порта В
Output_bit(READ_FIFO_A ,1); //PIN_C2.запретить
adcA = (adcA > 200) ? 200 : adcA; //ограничитель до выбранной величины
y = (255 - adcA) + y_pos_A; // разворот на 180° по вертикали и сдвиг
if (yy>y) front(x,yy,y); // Рисуем фронт A
if (yy<y) spad(x,yy,y); // Рисуем спад A
pixel(x,y,1); // Рисуем вершину A
}
}
В итоге мы избавились от лишнего цикла. А также освободили 1Кб RAM
Может, конечно, я что-то упустил - в следствии не полного понимания общего алгоритма работы, но помоему должно работать
В частности мне совсем непонятна строка:
Код
if( xx >= 255 ) xx = xx - 255; //приводим к int8
Перед этой строчкой в xx лежит индекс в буфере указывающий на место синхронизации (пересечение sync_volume_A в нужном направлении). Если я правильно понял нужно просто отрисоваь буфер с этого места на экране. Это и произойдет, если xx<255. А в противном случае вы отнимете 255 и точка синхронизации окажется в конце отрисовки... Не получиться ли у вас, что картинка начнет скакать?
andreichk
Mar 20 2008, 18:36
if( xx >= 255 ) xx = xx - 255; //приводим к int8
тут , как я себе представляю, смысл в том, чтобы хх укладывалось в интервал от 0 до 255, так как сам буфер в 4 раза больше. хх- это координата точки и поскольку момент захвата синхронизации может наступить за пределами этого диапазона, то эта конструкция всё равно установит этот момент в начало.
потому что в цикле начала отрисовки for(x=1;x<255;x++){
лежит другая переменная.
ЗЫ.попробовал ваш код- он работает, но если нет сигнала, то на экране не прорисовывается прямая, как в обычном осциллографе.Как-то не привычно, создаётся впечатление, что что-то не работает.
andreichk
Mar 20 2008, 19:53
кстати вопрос имею- чем два раза IF лучше одного SWITCH?
это я про синхронизацию