Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 08, 2014 10:10:22
Можно использовать указатель.
Здесь можно немножко помяукать :)
https://radiokot.ru:443/forum/
для MCS51 характерно "сопоставлять" переменные с определенными адресами в ОЗУ. по-моему, в кейле для этого есть расширение в виде "оператора" at или @ - точно не знаю, но вы можете посмотреть в любом хидере на периферию конкретного МК как там определены SFR-регистры, они точно привязаны к адресам...greenled писал(а):Доброго всем дня! Пишу тут прогу для МК с архитектурой 8051 на Си в Keil, увы, уровень владения языком невысок, но интересует такой вопрос: как ассоциировать с переменной какую-либо ячейку памяти данных? Делать ассемблерную вставку или можно как-то стандартными средствами кейловского си обойтись?
О как. Была память данных, стала память программ.greenled писал(а):как ассоциировать с переменной какую-либо ячейку памяти данных?
...
МК изредка принимал коэффициенты для ацп и хранил у себя во флеше
Код: Выделить всё
TYPE *b=0x????; // TYPE заменить на желаемый тип данных
#define A (*b) // обращение будет именно через А
#define B (*(TYPE*)0x????) // или так, если нет желания отъедать память лишней переменнойЭта "кухня" происходит в стартап коде, который пишется на асме. Из него и происходит вызов main().Ехан писал(а):как на с++ определить вектор этого прерывания мне найти не удалось. :\
Не навыкрутасничил, не знаю как. А стек боюсь использовать, как бы не послал куда не надоKavka писал(а):Да, там находиться не main. Там стоит rjmp на процедуру инициализации стека и RAM, а потом управление передаётся на main.
Если, конечно, вы сами ничего не навыкрутасничали.
Код: Выделить всё
//--------файл DEBUGER_SET---------------
#ifndef DEBUGER_SET_H
#define DEBUGER_SET_H
#define __DEBUG__ 0 // 0-Отладка выкл 1-отладка вкл
#define DEBUG_MENU 0
#define DEBUG_MENU1 0
#define __DEBUG_1WIRE__ 0 //
#endif
//--------MAIN-----------------------
#ifdef DEBUG_MENU1
case BUTT_OK:{
add_queue_write(0,(unsigned int)¤t_type_eeprom);
add_queue_write(0,(unsigned int)¤t_type_eeprom+1);
add_queue_write(0,(unsigned int)¤t_type_eeprom+2);
add_queue_write(0,(unsigned int)¤t_type_eeprom+3);
DEBUGER("RESIAVER=COMPLEATED",0,0,MESSENGER,TYPE_ADC);
break;
}
case BUTT_UP:{
//adc_main=adc_main+1;
break;
}
case BUTT_DW:{
/// adc_main=adc_main-1;
break;
}
#endif
Код: Выделить всё
unsigned long int design_value @0x0100;
unsigned long int design_result @0x0101;
design_value=345;
design_value=(unsigned long int)design_value*10;
//design_value=(design_value>>8); // design_value=U_power/K; K=256
design_result=design_result;Код: Выделить всё
// design_value1=(design_value1>>9);
LDS R26,_design_value1
LDS R27,_design_value1+1
LDS R24,_design_value1+2
LDS R25,_design_value1+3
LDI R30,LOW(9)
CALL __LSRD12
STS _design_value1,R30
STS _design_value1+1,R31
STS _design_value1+2,R22
STS _design_value1+3,R23
__LSRD12:
TST R30
MOV R0,R30
MOVW R30,R26
MOVW R22,R24
BREQ __LSRD12R
__LSRD12L:
LSR R23
ROR R22
ROR R31
ROR R30
DEC R0
BRNE __LSRD12L
__LSRD12R:
RETКод: Выделить всё
static union{
char bytes[4];
unsigned long int word32;
} data;Код: Выделить всё
char data8[5]={0,0,0,0,0}; // 1 байт лишний, он будет занулять старший байт
unsigned long *ptr1;
unsigned long *ptr2;
ptr1=(unsigned long*) &data8[0];
ptr2=(unsigned long*) &data8[1];
*ptr1 = my_data32;
new_data = *ptr2; Код: Выделить всё
static union{
long normal;
struct{
uint8_t dummy; // никогда не используется
long div256;
}
} my_var;
my_var.normal = 0xFF000000;
// деленное на 256 получится так
long x = my_var.div256; // x == 0x00FF0000;
Код: Выделить всё
29: gg = LONG_VALUE_DIV256(hh);
+00000033: 91800061 LDS R24,0x0061 Load direct from data space
+00000035: 91900062 LDS R25,0x0062 Load direct from data space
+00000037: 91A00063 LDS R26,0x0063 Load direct from data space
+00000039: 91B00064 LDS R27,0x0064 Load direct from data space
+0000003B: 70B0 ANDI R27,0x00 Logical AND with immediate
+0000003C: 93800068 STS 0x0068,R24 Store direct to data space
+0000003E: 93900069 STS 0x0069,R25 Store direct to data space
+00000040: 93A0006A STS 0x006A,R26 Store direct to data space
+00000042: 93B0006B STS 0x006B,R27 Store direct to data space
Код: Выделить всё
/* DS18x20 Термометр на 2x7-сегментном индикаторе с индикацией полярности на 1х16-сегментном индикаторе
Дата : Январь 2015
МК : AT89C2051, XL : 12МГц */
// Конфигурируем микроконтроллер
sbit OW_Bit at P3_7_bit; // задаем пин для подключения датчика температуры
sbit dgt_3 at P3.B1; // контролирующие пины семисегментного индикатора
sbit dgt_2 at P3.B2;
sbit dgt_1 at P3.B3;
unsigned char SG=0;
int Digit1,Digit2,Digit3;
// Соответствующие цифры для вывода на семисегментный индикатор
// минус плюс пусто
// 0 1 2 3 4 5 6 7 8 9 10 11 12
char number[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFC,0xFF};
void MUX() org IVT_ADDR_ET0 // используем прерывание переполнения Timer0
{
TL0=0x36; // загружаем LSB & MSB значения
TH0=0xf6;
P1=0xFF;
dgt_1 = dgt_2 = dgt_3 = 0;
SG++;
SG=SG%3;
switch(SG){
case 0: P1=number[Digit1];
dgt_1 = 1;
break;
case 1: P1=number[Digit2];
dgt_2 = 1;
break;
case 2: P1=number[Digit3];
dgt_3 = 1;
break;
}
}
// Выбор датчика DS18B20 или DS18S20
// DS18B20 отличается от DS18S20 смещением значения температуры на 3 разряда
const unsigned short TEMP_RESOLUTION = 9; //Поставьте ’12’ для DS18B20 или ‘9’ для DS18S20
unsigned temp;
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
// проверка отрицательной температуры
if (temp2write & 0x8000) {
Digit3 = 10; //если да показать минус
temp2write = ~temp2write + 1; // и инвертировать температуру
}
else
Digit3 = 11; //иначе показать плюс
// задаем смещение разрядов температуры в зависимости от семейства датчиков
temp_whole = temp2write >> RES_SHIFT ;
// разделяем температуру на разряды
if (temp_whole/100)
Digit3 = temp_whole/100; // извлечь сотни градуса
Digit2 = (temp_whole/10)%10; // извлечь десятки градуса
Digit1 = temp_whole%10; // извлечь единицы градуса
if ((Digit1 == 0) & (Digit2 == 0) & (Digit3 != 1)) Digit3 = 12; //при нуле градусов плюс отключить
if ((Digit2 == 0) & (Digit3 != 1)) { Digit2 = Digit1; Digit1 = 12; } //если температура меньше 10 смещаем разряд влево
if (Ow_Reset()) Digit1=Digit2=Digit3=10; //если датчик не подключен показать все минусы
}
void main() {
TMOD=0x01; // Инициализация Timer 0
TL0=0x36; // Задаем задержку 2.5мс для Timer 0
TH0=0xF6;
IE=0x82; // Здесь EA=1 & ET0=1
TR0_bit=1; // Старт timer0
//--- Основной цикл программы
do {
//--- Извлечение показаний температуры из датчика
Ow_Reset(); // 1wire сигнал сброса
Ow_Write(0xCC); // отправляем команду SKIP_ROM
Ow_Write(0x44); // отправляем команду CONVERT_T
Delay_us(120); // задержка 120мкс
Ow_Reset(); // 1wire сигнал сброса
Ow_Write(0xCC); // отправляем команду SKIP_ROM
Ow_Write(0xBE); // отправляем команду READING_SCRATCHPAD
temp = Ow_Read(); // считываем температуру
temp = (Ow_Read() << 8) + temp;
Display_Temperature(temp); // отобразить температуру
Delay_ms(500); // задержка 500мс
} while (1);
} //конец