реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> char + char = int как такое сделать, Сделать из двух байт целое
bugor
сообщение Aug 27 2009, 17:10
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408



Ситуатция известная -
- результат АЦП их двух байт в разных банках.
- работает три канала.
- есть массив из трех int.
Надо младший и старший байты результата АЦП обьединить в три целых переменных в массиве.

Чегото не получается никак - уже который раз пытаюсь. В AVR наких проблем нету, а на PIC редко пишу - направьте где посмотреть как это делается? Надо на СИ.
Go to the top of the page
 
+Quote Post
*antzol*
сообщение Aug 27 2009, 17:24
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 6-11-07
Пользователь №: 32 085



Это не подойдёт?
int result = ((int)highByte << 8) + lowByte;
Go to the top of the page
 
+Quote Post
bugor
сообщение Aug 27 2009, 18:01
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408



Цитата(*antzol* @ Aug 27 2009, 21:24) *
Это не подойдёт?
int result = ((int)highByte << 8) + lowByte;


HTEC PIC ругается - degenerate unsigned comparison

volatile unsigned int U[3] @ 0x20; //массив

ADRESH и ADRESL - это байты результата

надо в U[0] поместить ADRESH и ADRESL первого преобразования
в U[1] -----------------------------------второго преобразования и тд

Ммссив надо как то в цикле индексировать по счетчику каналов.
Go to the top of the page
 
+Quote Post
*antzol*
сообщение Aug 27 2009, 19:03
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 6-11-07
Пользователь №: 32 085



За правильность не ручаюсь, т.к. с пиками давно не работал, а в HTEC PIC вообще не писал. smile.gif
Код
char i;
for (i = 0; i < 3; i++)
{
   ADCON0 &= 0xC3;     // сброс выбора входа
   ADCON0 |= (i<<3);    // выбор входа

   // тут надо вставить задержку

   ADCON0 |= (1<<2);  // запуск преобразования
   while (ADCON0 & (1<<2));  // ожидание завершения преобразования
   u[i] = ADRESH;
   u[i] <<=8;
   u[i] +=ADRESL;
}
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 27 2009, 19:07
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(bugor @ Aug 28 2009, 00:01) *
HTEC PIC ругается - degenerate unsigned comparison
Видимо потому, что перед сдвигом надо приводить к типу unsigned int, а не (signed) int. Или использовать временную локальную переменную типа unsigned int .
Go to the top of the page
 
+Quote Post
*antzol*
сообщение Aug 27 2009, 19:17
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 6-11-07
Пользователь №: 32 085



...

Сообщение отредактировал *antzol* - Aug 27 2009, 19:23
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 27 2009, 19:50
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



А нельзя типа такого?
Код
short int adc_mass[3];  // или int16_t в духе С99 ???
char *adc_byte;           // или int8_t в духе С99 ???
adc_byte = (char*)adc_mass;
*(adc_byte++) = LOW_BYTE_ADC1;    // не знаю как называются, но
*(adc_byte++) = HIGH_BYTE_ADC1;  // допустим так...
/*
и т.д. для остальных каналов АЦП
*/

Я есесно в пиках и хитеке ни гугу. Это, так сказать, лишь идея.... laughing.gif
Go to the top of the page
 
+Quote Post
bugor
сообщение Aug 27 2009, 20:12
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408



Цитата(*antzol* @ Aug 27 2009, 23:03) *
За правильность не ручаюсь, т.к. с пиками давно не работал, а в HTEC PIC вообще не писал. smile.gif


Скомпилировался и в железе запустился вроде - что за значения получаются завтра проверю. Спасибо.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Aug 27 2009, 22:40
Сообщение #9


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



char как и int - переменные со знаком. Если не знаете зачем вам нужен знак используйте unsigned.
И компилятор тут не при делах.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
bugor
сообщение Aug 28 2009, 07:35
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408



Цитата(Student Pupkin @ Aug 27 2009, 23:50) *
А нельзя типа такого?


Не работает - преобразование вешается, я с указателями пробовал и не работает с ними у меня этот компилятор - не пойму почему.
Судя по листингу он сам активно использует косвенную адресацию и гдето там и происходит глюк, а как найти не знаю.
Вот полный код который компилируется но не работает - подскажите где ошибка.
CODE
//---------------------------------------
// Процессор PIC12F675
// Fosc = 4MHz Генератор RC-внутренний
// HI-TECH 8.05LP1
//---------------------------------------

#include <pic.h>
#include <math.h>

__CONFIG(WDTDIS & INTIO & UNPROTECT & MCLRDIS & PWRTEN & BOREN );

#define warm_out GPIO5 //выход нагревателя
#define sound_out GPIO4 //выход pреле звука
#define start_out GPIO3 //вход выключателя нагрева

volatile unsigned char Temp, Count, Channel;
volatile unsigned int U[3];// @ 0x20; //массив из трех двухбайтных элементов
volatile unsigned char *pU =(char*)U; //указатель на адрес 1го элемента массива

//МАКРОСЫ
//-----------------------------------------
#define TESTBIT(ADRESS,BIT) (ADRESS & (1<<BIT))
#define SETBIT(ADRESS,BIT) (ADRESS |= (1<<BIT))
#define CLEARBIT(ADRESS,BIT) (ADRESS &= ~(1<<BIT))
//================================
//задержка для A/D преобразования
//================================
void ADDelay() { //задержка 10uS
static unsigned char i;
i = 3; //Генератор 4Mhz, период 3uS,
while(i > 0) { //переменная равна 3 плюс смещение
i--;
}
}
//================================
//Инициализация A/D преобразования
//================================
void InitAD() {
ADIE = 1; //Разрешить прерывания от АЦП
ADCON0 = Channel; //Генегатор внутр RC + номер канала
ADIF = 0; //очистить флаг прерывания от АЦП
PEIE = 1; //Разрешить переферийные прерывания
asm("nop");
}
//==========================================================================
// MAIN
//==========================================================================
void main(void) {

GPIO = 0b00000000; // порты в ноль
TRISIO = 0b10001111; // GP4-5 на выход
OPTION = 0b00000110; // R-up выкл, делитель 1:128 к TMR0
VRCON = 0x00; // выключить источнок опорного напряжения
WPU = 0b00000000; // gp0 gp5 подтягивающие резисторы выключены
IOCB = 0x00; // запрет прерываний по входам
CMCON = 0b00000111; // компаратор выключен
INTCON =0b10000000; // разреш прерывания
ANSEL =0b01010111;
warm_out = 1;

Count = 0; //первый запуск ацп
Channel = 129; //канал ацп 0
InitAD();
ADDelay();
SETBIT(ADCON0,1);

while(1) {
ei();
asm("nop");
di();
}
}
//================================
//Обработка прерываний
//================================
void interrupt ADC() {

sound_out = 1; //индикатор работы ацп

*(pU) = ADRESH; //старший байт в первый элемент массива
*(pU++) = ADRESL; //младший байт во второй элемент массива
//точно также в 3-4 и в 5-6 элементы по циклу
if(Count++ < 3) {
Channel = Channel + 8; //загрузить другой канал
}else {
Channel = 129; //10000001b загрузка канала АЦП 0
Count = 0; //перезагрузить счетчик каналов
*pU = U[0]; //перегружаем адрес первого элемента массива
}

InitAD();
ADDelay(); //задержка на 2xTad для восстановления

sound_out=0;

ADDelay();
SETBIT(ADCON0,1); //Запуск A/D преобразования
}


По посту №4 работает АЦП и даже есть результат но понятно это по изменению младшего байта результата, а вот когда пытаюсь запихать два байта в целое то сравнения не работают то есть не получается нормальног INT из двух CHAR.
Причина редактирования: Нарушение п.3.4 Правил форума.
Go to the top of the page
 
+Quote Post
Kane
сообщение Aug 28 2009, 08:13
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 36
Регистрация: 10-02-06
Пользователь №: 14 185



Вот на что обратил внимание:

Цитата(bugor @ Aug 28 2009, 11:35) *
Код
    while(1) {
         ei();
         asm("nop");
         di();
    }


Зачем в цикле запрещаете прерывания и снова разрешаете (если я правильно угадал смысл ei() и di())?

Цитата(bugor @ Aug 28 2009, 11:35) *
Код
      *(pU) = ADRESH;             //старший байт в первый элемент массива
      *(pU++) = ADRESL;           //младший байт во второй элемент массива
                                  //точно также в 3-4 и в 5-6 элементы по циклу


в этом куске младший байт всегда будет перетираться старшим байтом.
Go to the top of the page
 
+Quote Post
bugor
сообщение Aug 28 2009, 08:46
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408



Цитата(Kane @ Aug 28 2009, 12:13) *
Вот на что обратил внимание:

Зачем в цикле запрещаете прерывания и снова разрешаете (если я правильно угадал смысл ei() и di())?

в этом куске младший байт всегда будет перетираться старшим байтом.


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

Я уже посмотрел по листингу что происходит затирка, а как сделать чтобы этого небыло не знаю.
Но дело еще в том, что код не работает не в смысле неправильного формирования данных а в том смысле что преобразования АЦП не производятся - то есть на выходе индикатора должен быть что то подобие меандра, а ничего не происходит - висит 1 - то есть в прерывание вход есть, а выхода нет wacko.gif
Причем это наблюдается если начинаю использовать указатели - если без них то циклическое преобразование есть - но с данными непонятно что происходит.

Сообщение отредактировал bugor - Aug 28 2009, 08:47
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Aug 28 2009, 09:30
Сообщение #13


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Цитата
После запрещения прерывания будут вычисления

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

Не запрещайте прерываний без четкого понимания - для чего именно вам это нужно именно в данный момент. В данной программе данный код не имеет смысла. Даже для якобы будущих вычислений.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
bugor
сообщение Aug 28 2009, 09:50
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408



Убрал запрещения и собственно ничего не изменилось - нет преобразований АЦП.
Go to the top of the page
 
+Quote Post
tag
сообщение Aug 28 2009, 09:57
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561



Код
  *(pU) = ADRESH;             //старший байт в первый элемент массива
      *(pU++) = ADRESL;           //младший байт во второй элемент массива


не понятно где и как инициализируется pU?
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 07:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.0147 секунд с 7
ELECTRONIX ©2004-2016