⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sinegen.c

📁 * Use 10 MHz crystal frequency. * Use Timer0 for ten millisecond looptime. * Blink "Alive" LED e
💻 C
字号:


#include "config.h"
#include "serial.c"
#include "serio.c"
#include "i2cmsu.c"

// generates a sinewave using a 64 step  or 16 step table 

// Uses timer2 

#define DAC 0x58        // I2C DAC 01011000 

#include "sinegen.h"

int update_dac(unsigned char val) {
  i2c_start();
  i2c_put(DAC);
  i2c_put(0x00);
  i2c_put(val);
  i2c_stop();
}

char dac_value;
char dac_flag;
char pr_flag;

#define MIN_PERIOD 25
#define MAX_PERIOD 100

// i2c clock freq = Fosc/4(SSPAD+1)
// 100000(SSPPAD+1) = 3686400/4
//  SSPAD = 8.2, use 8, will be close to 100 Khz


// assumes left justification, only returns upper 7 bits,
//  limits value between min_period and max_period 

void update_period(void){

  unsigned char rval;
  // read ADC result, use as period, start new conversion 
  rval = ADRESH >> 1; // only keep upper 7 bits
  if (rval < MIN_PERIOD) rval = MIN_PERIOD;
  if (rval > MAX_PERIOD) rval = MAX_PERIOD;
  PR2 = rval;  // set timer2 period register 
  // start new conversion 
  GODONE = 1;
}


unsigned char sineptr;
unsigned char tabmax;

#if defined(HI_TECH_C)
void interrupt timer2_isr(void)
#endif
#if defined(__18CXX)
#pragma interrupt timer2_isr
void timer2_isr(void)
#endif
{
  sineptr++;
  if (sineptr == tabmax){
    sineptr = 0;
    pr_flag = 1;
  }
  dac_flag = 1;
  TMR2IF = 0; // clear timer2 interupt flag 
}


void main(void)
{
  char inchar;

  serial_init(95,1); // 19200 in HSPLL mode, crystal = 7.3728 MHz 

  if (POR == 0){  // bit 2 in RCON register, cleared to 0 on power-up reset
    POR = 1;  // setting to bit to 1 means that will remain a '1' for MCLR reset
    printf("Power-on reset has occurred.");
    pcrlf();
  }
  if (TO == 0) {
    SWDTEN = 0; // disable watchdog timer
    printf("Watchdog timer reset has occurred, press reset to recover.\n");
    pcrlf();
    while(1);
  }
  SWDTEN = 1;  // enable watchdog timer

  i2c_init(17); // about 400Khz  for HSPLL mode, crystal = 7.3728 MHz 

  // configure A/D inputs of PORT A to be all digital inputs 
  ADCON1 = 0x0E;         // Port A analog input, right justification of result 
  TRISA = 0xFF;		// all bits input 

  ADCON0 = 0x80;  // sampling freq = Fsoc/32, channel 0 
  ADON = 1; // turn on ADC

  printf("ADC is configured!!!");
  pcrlf();

  pr_flag = 0;
  dac_flag = 0;
  sineptr = 0;

  tabmax = 16;
  printf("Enter '1' for 64 entry table, anything else chooses 16 ");
  inchar=getch();
  pcrlf();
  if (inchar == '1') tabmax = 64;

  // start first conversion. At end of each cycle, do new conversion 
  GODONE = 1;
  while (GODONE);  // wait for end of conversion 

  printf("First conversion ");
  pcrlf();
 
  PR2 = MAX_PERIOD;
  if (tabmax == 16)
    update_dac(sine16tab[sineptr]);
  else  update_dac(sine64tab[sineptr]);

  // configure timer 2
  // post scale of 3 
  TOUTPS3 = 0; TOUTPS2 = 0; TOUTPS1 = 1;  TOUTPS0 = 0;

  // pre scale of 4 
  T2CKPS1 = 0;  T2CKPS0 = 1;

  // start timer 2 
  TMR2ON = 1 ;

  printf("Entered Loop ");
  pcrlf();

  // enable interrupts
  IPEN = 0;  // priorities disabled 
  TMR2IF = 0; // clear timer2 interupt flag 
  TMR2IE = 1;   // receive interrupt enable 
  PEIE = 1;  
  GIE = 1;  

  while(1) {
    CLRWDT();    //asm("clrwdt"); 
    if(dac_flag) {
      if (tabmax == 16)
	update_dac(sine16tab[sineptr]);
      else  update_dac(sine64tab[sineptr]);
      dac_flag = 0;
      if (pr_flag) {
	update_period();
	pr_flag = 0;
      }
    }
  }
}


//for MCC18, place the interrupt vector goto
#if defined(__18CXX)
#if defined(HIGH_INTERRUPT)
#pragma code HighVector=HIGH_INTERRUPT
#else
#pragma code HighVector=0x0008  
#endif
void HighVector (void)
{
    _asm goto timer2_isr _endasm
}
#pragma code
#endif



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -