Перейти к содержанию

Передача Данных Через Uart


goodking

Рекомендуемые сообщения

Привет! Подскажите, как правильно инициализировать УАПП, и вообще, какой алгоритм работы с ним МК SiLabs c8051F120, документацию читал, написал програмку, информация почему-то не передается??

#include "c8051F120.h"
#include <stdio.h>
sfr16 RCAP3=202;
sfr16 TMR3=204;
sfr16 ADC0=0xbe;//адрес sfr (16 бит) 
sfr16 RCAP4=0xe4;
sfr16 TMR4=0xcc;
long temperature;
#define SYSCLK 3062500 
void Timer_Init(int counts);
void Timer4_Init(int counts);
void ADC_Init();
void Voltage_Reference_Init();
void UART_Init();
unsigned char UART; 
void main(void)
{  
WDTCN   = 0xDE;
WDTCN   = 0xAD;
   SFRPAGE   = CONFIG_PAGE;
P0MDOUT   = 0x01;
   XBR0      = 0x04;
   XBR2      = 0x40;

EA=0;
Voltage_Reference_Init();
UART_Init();
   ADC_Init();
Timer_Init(SYSCLK/12/10);
EIP2      = 0x01;
EA=1;

while (1);
}



void Timer_Init( int counts)

{
   SFRPAGE   = TMR3_PAGE;
   TMR3CN    = 0x04;//включение таймера 2(2 бит в 1)
   TMR3CF    = 0x08;//конфигурация SYSCLK/8
   RCAP3=-counts;//SYSCLK/12/10 с противоположным значением заносится в байт захвата 
TR3=1;// включение таймера 3
EIE2      = 0x01;
}


void UART_Init()
{
   SFRPAGE   = UART0_PAGE;
   SCON0     = 0x10;
   SFRPAGE   = TIMER01_PAGE;
   TMOD      = 0x20;
   IE        = 0x10;

}

void ADC_Init()
{
   SFRPAGE   = ADC0_PAGE;
   AMX0SL    = 0x08;// выбор канала мультиплексора (температурный датчик)
   ADC0CF    = 0xF9;//определение входной частоты(internal amplifier gain)
   ADC0CN    = 0x85;//управление АЦП(разрешение, прерывание по переп. таймера 3..)

}

void Voltage_Reference_Init()
{
   SFRPAGE   = ADC0_PAGE;
   REF0CN    = 0x07;// управление опорным напряжением(разрешение BIAS, источник опорного напр., разрешение темп.датчика)
}


void UART_ISR (void) interrupt 4
{
TI0=0;
RI0=0;
SFRPAGE = UART0_PAGE;
printf("%d",temperature);
}


void Timer3_ISR (void) interrupt 14

{   
   TF3=0;                      //--  сброс флага TF3 ожидание 
   SFRPAGE   = ADC0_PAGE;                  //--  окончания преобразования АЦП0
   while  ((ADC0CN& 0x20)==0)          //--  опрос AD0INT->l
   temperature = ADC0;                    //--  чтение данных АЦП0
ADC0CN &=  0xDF;                       //--  сброс AD0INT
}




Изменено пользователем goodking
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Ну во первых, прерывание возникает после приёма 1-го байта или окончания передачи 1-го байта. В вашем коде вы пытаетесь передать сразу целую строку в обработчике прерывания от UARTа.

void UART_ISR (void) interrupt 4

{

TI0=0;

RI0=0;

SFRPAGE = UART0_PAGE;

 printf("%d",temperature); // Это не допустимо

}

Для начала передачи через UART нужно что-либо отправить в регистр SBUF, чего я не наблюдаю. Либо использовать функцию printf вне обработчика прерывания от UART.

void Timer3_ISR (void) interrupt 14

{  

    TF3=0;                      //--  сброс флага TF3 ожидание

    SFRPAGE   = ADC0_PAGE;                  //--  окончания преобразования АЦП0

     while  ((ADC0CN& 0x20)==0)          //--  опрос AD0INT->l     // недопустимо делать циклы в обработчиках прерывания!

    temperature = ADC0;                    //--  чтение данных АЦП0

    ADC0CN &=  0xDF;                       //--  сброс AD0INT

}

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

Пока ты жив, надежда есть.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Для начала передачи через UART нужно что-либо отправить в регистр SBUF, чего я не наблюдаю. Либо использовать функцию printf вне обработчика прерывания от UART.
Вроде да, но почему при запуске этой программы(из стандартных примеров) в которой регистр SBUF вообще не упоминается, данные все-равно передаються?

#include <c8051f120.h>                 // SFR declarations
#include <stdio.h>

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 ADC0     = 0xbe;                 // ADC0 data
sfr16 ADC0GT   = 0xc4;                 // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                 // ADC0 less than window
sfr16 RCAP2    = 0xca;                 // Timer2 capture/reload
sfr16 RCAP3    = 0xca;                 // Timer3 capture/reload
sfr16 RCAP4    = 0xca;                 // Timer4 capture/reload
sfr16 TMR2     = 0xcc;                 // Timer2
sfr16 TMR3     = 0xcc;                 // Timer3
sfr16 TMR4     = 0xcc;                 // Timer4
sfr16 DAC0     = 0xd2;                 // DAC0 data
sfr16 DAC1     = 0xd2;                 // DAC1 data
sfr16 PCA0CP5  = 0xe1;                 // PCA0 Module 5 capture
sfr16 PCA0CP2  = 0xe9;                 // PCA0 Module 2 capture
sfr16 PCA0CP3  = 0xeb;                 // PCA0 Module 3 capture
sfr16 PCA0CP4  = 0xed;                 // PCA0 Module 4 capture
sfr16 PCA0     = 0xf9;                 // PCA0 counter
sfr16 PCA0CP0  = 0xfb;                 // PCA0 Module 0 capture
sfr16 PCA0CP1  = 0xfd;                 // PCA0 Module 1 capture

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define BAUDRATE     115200            // Baud rate of UART in bps
#define INTCLK       24500000          // Internal oscillator frequency in Hz
#define SYSCLK       49000000          // Output of PLL derived from (INTCLK*2)
#define SAMPLE_RATE  50000             // Sample frequency in Hz
#define INT_DEC      256               // integrate and decimate ratio

sbit LED = P1^6;                       // LED='1' means ON
sbit SW1 = P3^7;                       // SW1='0' means switch pressed

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void SYSCLK_Init (void);
void PORT_Init (void);
void UART1_Init (void);
void ADC0_Init (void);
void Timer3_Init (int counts);
void ADC0_ISR (void);
void wait_ms (int ms);
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------

long result;                           // ADC0 decimated value

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void) {
  long temperature;                   // temperature in hundredths of a
                                      // degree C
  int temp_int, temp_frac;            // integer and fractional portions of
                                      // temperature

  WDTCN = 0xde;                       // disable watchdog timer
  WDTCN = 0xad;

  SYSCLK_Init ();                     // initialize oscillator
  PORT_Init ();                       // initialize crossbar and GPIO
  UART1_Init ();                      // initialize UART1
  Timer3_Init (SYSCLK/SAMPLE_RATE);   // initialize Timer3 to overflow at
                                      // sample rate

  ADC0_Init ();                       // init ADC

  SFRPAGE = ADC0_PAGE;
  AD0EN = 1;                          // enable ADC

  EA = 1;                             // Enable global interrupts

  while (1) {
     EA = 0;                          // disable interrupts
     temperature = result;
     EA = 1;                          // re-enable interrupts

     // calculate temperature in hundredths of a degree
     temperature = temperature - 42380;
     temperature = (temperature * 100L) / 156;
     temp_int = temperature / 100;
     temp_frac = temperature - (temp_int * 100);

     SFRPAGE = UART1_PAGE;
     printf ("Temperature is %+02d.%02d\n", temp_int, temp_frac);

     SFRPAGE = CONFIG_PAGE;
     LED = ~SW1;                      // LED reflects state of switch

     wait_ms(50);                     // wait 50 milliseconds
  }
}

//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// wait_ms
//-----------------------------------------------------------------------------
//
// This routine inserts a delay of <ms> milliseconds.
//
void wait_ms(int ms)
{
  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

  SFRPAGE = TMR2_PAGE;

  TMR2CN = 0x00;                      // Stop Timer3; Clear TF3;
  TMR2CF = 0x00;                      // use SYSCLK/12 as timebase

  RCAP2 = -(SYSCLK/1000/12);          // Timer 2 overflows at 1 kHz
  TMR2 = RCAP2;

  ET2 = 0;                            // Disable Timer 2 interrupts

  TR2 = 1;                            // Start Timer 2

  while(ms){
     TF2 = 0;
     while(!TF2);                     // wait until timer overflows
     ms--;                            // decrement ms
  }

  TR2 = 0;                            // Stop Timer 2

  SFRPAGE = SFRPAGE_SAVE;             // Restore SFRPAGE
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal oscillator
// at 24.5 MHz multiplied by two using the PLL.
//
void SYSCLK_Init (void)
{
  int i;                              // software timer

  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

  SFRPAGE = CONFIG_PAGE;              // set SFR page

  OSCICN = 0x83;                      // set internal oscillator to run
                                      // at its maximum frequency

  CLKSEL = 0x00;                      // Select the internal osc. as
                                      // the SYSCLK source

  //Turn on the PLL and increase the system clock by a factor of M/N = 2
  SFRPAGE = CONFIG_PAGE;

  PLL0CN  = 0x00;                     // Set internal osc. as PLL source
  SFRPAGE = LEGACY_PAGE;
  FLSCL   = 0x10;                     // Set FLASH read time for 50MHz clk
                                      // or less
  SFRPAGE = CONFIG_PAGE;
  PLL0CN |= 0x01;                     // Enable Power to PLL
  PLL0DIV = 0x01;                     // Set Pre-divide value to N (N = 1)
  PLL0FLT = 0x01;                     // Set the PLL filter register for
                                      // a reference clock from 19 - 30 MHz
                                      // and an output clock from 45 - 80 MHz
  PLL0MUL = 0x02;                     // Multiply SYSCLK by M (M = 2)

  for (i=0; i < 256; i++) ;           // Wait at least 5us
  PLL0CN  |= 0x02;                    // Enable the PLL
  while(!(PLL0CN & 0x10));            // Wait until PLL frequency is locked
  CLKSEL  = 0x02;                     // Select PLL as SYSCLK source

  SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// This routine configures the crossbar and GPIO ports.
//
void PORT_Init (void)
{
  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

  SFRPAGE = CONFIG_PAGE;              // set SFR page

  XBR0     = 0x00;
  XBR1     = 0x00;
  XBR2     = 0x44;                    // Enable crossbar and weak pull-up
                                      // Enable UART1

  P0MDOUT |= 0x01;                    // Set TX1 pin to push-pull
  P1MDOUT |= 0x40;                    // Set P1.6(LED) to push-pull

  SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page
}

//-----------------------------------------------------------------------------
// UART1_Init
//-----------------------------------------------------------------------------
//
// Configure the UART1 using Timer1, for <baudrate> and 8-N-1.
//
void UART1_Init (void)
{
  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

  SFRPAGE = UART1_PAGE;
  SCON1   = 0x10;                     // SCON1: mode 0, 8-bit UART, enable RX

  SFRPAGE = TIMER01_PAGE;
  TMOD   &= ~0xF0;
  TMOD   |=  0x20;                    // TMOD: timer 1, mode 2, 8-bit reload


  if (SYSCLK/BAUDRATE/2/256 < 1) {
     TH1 = -(SYSCLK/BAUDRATE/2);
     CKCON |= 0x10;                   // T1M = 1; SCA1:0 = xx
  } else if (SYSCLK/BAUDRATE/2/256 < 4) {
     TH1 = -(SYSCLK/BAUDRATE/2/4);
     CKCON &= ~0x13;                  // Clear all T1 related bits
     CKCON |=  0x01;                  // T1M = 0; SCA1:0 = 01
  } else if (SYSCLK/BAUDRATE/2/256 < 12) {
     TH1 = -(SYSCLK/BAUDRATE/2/12);
     CKCON &= ~0x13;                  // T1M = 0; SCA1:0 = 00
  } else {
     TH1 = -(SYSCLK/BAUDRATE/2/48);
     CKCON &= ~0x13;                  // Clear all T1 related bits
     CKCON |=  0x02;                  // T1M = 0; SCA1:0 = 10
  }

  TL1 = TH1;                          // initialize Timer1
  TR1 = 1;                            // start Timer1

  SFRPAGE = UART1_PAGE;
  TI1 = 1;                            // Indicate TX1 ready

  SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page

}

//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Configure ADC0 to use Timer3 overflows as conversion source, to
// generate an interrupt on conversion complete, and to use left-justified
// output mode.  Enables ADC end of conversion interrupt. Leaves ADC disabled.
//
void ADC0_Init (void)
{
  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

  SFRPAGE = ADC0_PAGE;

  ADC0CN = 0x05;                      // ADC0 disabled; normal tracking
                                      // mode; ADC0 conversions are initiated
                                      // on overflow of Timer3; ADC0 data is
                                      // left-justified
  REF0CN = 0x07;                      // enable temp sensor, on-chip VREF,
                                      // and VREF output buffer
  AMX0SL = 0x0f;                      // Select TEMP sens as ADC mux output
  ADC0CF = (SYSCLK/2500000) << 3;     // ADC conversion clock = 2.5MHz
  ADC0CF |= 0x01;                     // PGA gain = 2

  EIE2 |= 0x02;                       // enable ADC interrupts

  SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page
}

//-----------------------------------------------------------------------------
// Timer3_Init
//-----------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload at interval specified by <counts> (no
// interrupt generated) using SYSCLK as its time base.
//
void Timer3_Init (int counts)
{
  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

  SFRPAGE = TMR3_PAGE;

  TMR3CN = 0x00;                      // Stop Timer3; Clear TF3;
  TMR3CF = 0x08;                      // use SYSCLK as timebase

  RCAP3   = -counts;                  // Init reload values
  TMR3    = RCAP3;                    // set to reload immediately
  EIE2   &= ~0x01;                    // disable Timer3 interrupts
  TR3 = 1;                            // start Timer3

  SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page
}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// ADC0_ISR
//-----------------------------------------------------------------------------
//
// ADC0 end-of-conversion ISR
// Here we take the ADC0 sample, add it to a running total <accumulator>, and
// decrement our local decimation counter <int_dec>.  When <int_dec> reaches
// zero, we post the decimated result in the global variable <result>.
//
void ADC0_ISR (void) interrupt 15
{
  static unsigned int_dec=INT_DEC;    // integrate/decimate counter
                                      // we post a new result when
                                      // int_dec = 0
  static long accumulator=0L;         // here's where we integrate the
                                      // ADC samples

  AD0INT = 0;                         // clear ADC conversion complete
                                      // indicator

  accumulator += ADC0;                // read ADC value and add to running
                                      // total
  int_dec--;                          // update decimation counter

  if (int_dec == 0) {                 // if zero, then post result
     int_dec = INT_DEC;               // reset counter
     result = accumulator >> 8;
     accumulator = 0L;                // reset accumulator
  }
}

Ссылка на комментарий
Поделиться на другие сайты

Вы невнимательно читаете ответы. Я писал ранее

...Либо использовать функцию printf вне обработчика прерывания от UART.

Что и наблюдается в приведённом вами исходном тексте.

Пока ты жив, надежда есть.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...