📄 sinegen.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 + -