Monday, July 25, 2016

PIC Code Dumping Ground

Sorry this blog has become mostly a dumping ground for PIC code.

Sunday, April 3, 2016

Digital Noise Generator

This code makes digital noise using a PIC microcontroller (12f683).

Three signals are generated: Random noise on GP0, random triggers GP1, and random gates on GP2.

 /*
 * File:   Noise Generator 2 Routine.c
 * Author: Hans Mikelson
 *
 * Created on March 17, 2016, 1 PM
 */

#if defined(__XC)
    #include <xc.h>         /* XC8 General Include File */
#elif defined(HI_TECH_C)
    #include <htc.h>        /* HiTech General Include File */
#endif

#include <stdint.h>        /* For uint8_t definition */
#include <stdbool.h>       /* For true/false definition */
#include <stdlib.h>     /*rand()*/

#pragma config MCLRE=OFF,CP=OFF,WDTE=OFF,FOSC=INTOSCIO
#define _XTAL_FREQ 4000000
uint8_t sGPIO;
int gi,gi1,gr1,gr2,gr3,gi3,gr0,gr4;

void init()
{
    //Configure GPIO Port
    ANSEL =  0b00000000;  //Configure all GPIO pins as digital
    TRISIO = 0b11001100;  //Set GP# 1=inputs and 0=outputs
    OPTION_REGbits.nGPPU = 0;
    WPU = 0b00000100;     //Enable weak pullups=1
    //Configuer AD Convertor
    ADCON0 = 0x00;        //AD disabled
    ADRESH = 0x00;        //Init the AD Register
    //Configure Comparator
    CMCON0 = 0xFF;   // Comparator is turned off
    CMCON1 = 0x00;   // Comparator is turned off
    //Interrupt configuration
    //INTCON = 0x00;   //Disable all interrupts
    INTCONbits.INTF = 0;       // External interrupt on GP2 only
    OPTION_REGbits.INTEDG = 0; // 1=rising edge, 0=falling
    INTCONbits.INTE = 1;       // Enable external interrupt
    INTCONbits.GIE = 1;        // Global interrupt enable
}

void vdelay(int n)
{
    int i;
    for (i=0;i<=n;i++)
    {
     __delay_us(100);
    }
}

void scan_eyes(int n, int m, uint8_t led1, uint8_t led2) // PWM sweep high f to low f
{
 int i,j,k;
 int i1,i2,i3,pw1,pw2;
 uint8_t sGPIO;

 i1=1; i2=-1; pw1=0; pw2=n;
 sGPIO = GPIO;
 for (k=0;k<m;k++)
 {
  for (j=0;j<n;j++)
   {
    for (i=0;i<n;i++)
     {
      if (i>pw1)
       {
        sGPIO = sGPIO & ~led1;
       }
      else
       {
        sGPIO = sGPIO | led1;
       }
      if (i>pw2)
       {
        sGPIO = sGPIO & ~led2;
       }
      else
       {
        sGPIO = sGPIO | led2;
       }
      GPIO = sGPIO;
     }
    pw1 = pw1 + i1;
    pw2 = pw2 + i2;
   }
  i3 = i1; i1 = i2, i2 = i3;
 }
}

void noise0(uint8_t r3) // Pulse noise with different frequencies
{
 int r1;
 r1=rand() | 0b11111110;

 sGPIO = GPIO;
 //sGPIO = (sGPIO & 0b11111101);
 sGPIO = (sGPIO | 0b00000001) & r1;
 if (gr1<=0)
  {
   sGPIO = (sGPIO & 0b11101111);
  }
 if (gr2<=0)
  {
   gr0=(rand() & r3)+11;
   gr1=(rand() & r3)+11;
   gr2=gr1+gr0;
   gr3=10;
   gi3=-1;
   sGPIO = (sGPIO | 0b00010010);
  }
 gr2--;
 gr1--;
 if (gr3==0)
  {
   gi3=0;
   sGPIO = (sGPIO & 0b11111101);
  }
 gr3+=gi3;
 GPIO = sGPIO;
}

void noise1(int r3) // Pulse noise
{
 int r1;
 r1=rand() | 0b11111110;

 sGPIO = GPIO;
 sGPIO = (sGPIO | 0b00000001) & r1;
 if (gr1<=0)
  {
   sGPIO = (sGPIO & 0b11101111);
  }
 if (gr2<=0)
  {
   gr0=(rand() & gr4)+11;
   gr1=(rand() & gr4)+11;
   gr2=gr1+gr0;
   gr3=10;
   gi3=-1;
   sGPIO = (sGPIO | 0b00010010);
  }
 gr2--;
 gr1--;
 if (gr3==0)
  {
   gi3=0;
   sGPIO = (sGPIO & 0b11111101);
  }
 gr3+=gi3;
 GPIO = sGPIO;
}

void main()
{
    uint8_t r, d=20, rp=3;

    init();
    gi=0;
    gi3=0; gr3=10;
    GPIO = 0b00000000;
    gr0=(rand() & 0b1111111111)+11;
    gr1=(rand() & 0b1111111111)+11;
    gr2=gr1+gr0;
    scan_eyes(d,2,2,1);
    while(1)
    {
     switch (gi)
      {
       case 0:
           noise0(1);
       break;

       case 1:
         noise1(rand());
       break;

       default:
       scan_eyes(d,2,1,2);
      }
    }
}

void interrupt tc_int (void)
{
 if (INTCONbits.INTF==1)
  {
   INTCONbits.INTF = 0;
   gi=(gi+1)%3;
   vdelay(100);
     switch (gi)
      {
       case 0:
         gi3=0; gr3=10;
         GPIO = 0b00000000;
         gr0=(rand() & 0b1111111111)+11;
         gr1=(rand() & 0b1111111111)+11;
         gr2=gr1+gr0;
       break;

       case 1:
         gi3=0; gr3=10;
         GPIO = 0b00000000;
         gr4 = rand();
         gr0=(rand() & gr4)+11;
         gr1=(rand() & gr4)+11;
         gr2=gr1+gr0;
       break;

       default:
         GPIO = 0b00000000;
      }
  }
}


 

Saturday, March 26, 2016

Interrupt Generator and Curve Tracer

Just putting this code up so I can easily access it when I want to.  The curve tracer is an example of using PWM, the second file is an example of using an external interrupt.  This is for a 12f683 device.  I am working on putting this code into my mini-modular synthesizer.  I have a module that is based on the PIC12f683 that generates noise and random events.

/* 
 * File:   CurveTracerMain.c
 * Author: Hans Mikelson
 *
 * Created on March 17, 2016, 12:34 PM
 */

#if defined(__XC)
    #include <xc.h>         /* XC8 General Include File */
#elif defined(HI_TECH_C)
    #include <htc.h>        /* HiTech General Include File */
#endif

#include <stdint.h>        /* For uint8_t definition */
#include <stdbool.h>       /* For true/false definition */

#pragma config MCLRE=OFF,CP=OFF,WDTE=OFF,FOSC=INTOSCIO
#define _XTAL_FREQ 8000000
uint8_t sGPIO;
int gi;

void init()
{
    //Configure GPIO Port
    ANSEL =  0b00000000;  //Configure all GPIO pins as digital
    TRISIO = 0b11001100;  //Set GP# 1=inputs and 0=outputs
    OPTION_REGbits.nGPPU = 0;
    WPU = 0b00100100;     //Enable weak pullups=1
    //Configuer AD Convertor
    ADCON0 = 0x00;        //AD disabled
    ADRESH = 0x00;        //Init the AD Register
    //Configure Comparator
    CMCON0 = 0xFF;   // Comparator is turned off
    CMCON1 = 0x00;   // Comparator is turned off
    //Interrupt configuration
    INTCON = 0x00;   //Disable all interrupts
    //INTCONbits.INTF = 0;       // External interrupt on GP2 only
    //OPTION_REGbits.INTEDG = 0; // 1=rising edge, 0=falling
    //INTCONbits.INTE = 1;       // Enable external interrupt
    //INTCONbits.GIE = 1;        // Global interrupt enable
}

void vdelay(int n)
{
    int i;
    for (i=0;i<=n;i++)
    {
     __delay_us(100);
    }
}

void main()
{
 uint8_t r, d, rp=3, sPIR1, sCCP1CON, i=0, j=0, sCCPR1L, sGPIO; // ADC_result2;;

 init();
 gi=0;
 GPIO = 0b00000000;
 TRISIO = 0b11101100;  //Disable IO2
 PR2 = 0x0F;
 CCP1CON = 0b00111100;
 CCPR1L =  16; // 1,4,16
 sPIR1 = PIR1 & 0b11111101; //Clear TMR2IF
 PIR1 = sPIR1;
 T2CON = 0b00000101;
 while(1)
  {
   //Update PWM
   if (PIR1bits.TMR2IF == 1)
   {
    i=(i+1)%0x0F;
    TRISIO = 0b11101000;
    CCPR1L = i;
   }
  if (i == 0x00)
   {
      j=(j+1)%4;
      sGPIO = GPIO;
      sGPIO = ((sGPIO & 0b11111100) | j);
      GPIO = sGPIO;
   }
  }
}

/*
 * File:   Interrupt Test Routine.c
 * Author: Hans Mikelson
 *
 * Created on March 17, 2016, 1 PM
 */

#if defined(__XC)
    #include <xc.h>         /* XC8 General Include File */
#elif defined(HI_TECH_C)
    #include <htc.h>        /* HiTech General Include File */
#endif

#include <stdint.h>        /* For uint8_t definition */
#include <stdbool.h>       /* For true/false definition */

#pragma config MCLRE=OFF,CP=OFF,WDTE=OFF,FOSC=INTOSCIO
#define _XTAL_FREQ 4000000
uint8_t sGPIO;
int gi;

void init()
{
    //Configure GPIO Port
    ANSEL =  0b00000000;  //Configure all GPIO pins as digital
    TRISIO = 0b11001100;  //Set GP# 1=inputs and 0=outputs
    OPTION_REGbits.nGPPU = 0;
    WPU = 0b00100100;     //Enable weak pullups=1
    //Configuer AD Convertor
    ADCON0 = 0x00;        //AD disabled
    ADRESH = 0x00;        //Init the AD Register
    //Configure Comparator
    CMCON0 = 0xFF;   // Comparator is turned off
    CMCON1 = 0x00;   // Comparator is turned off
    //Interrupt configuration
    //INTCON = 0x00;   //Disable all interrupts
    INTCONbits.INTF = 0;       // External interrupt on GP2 only
    OPTION_REGbits.INTEDG = 0; // 1=rising edge, 0=falling
    INTCONbits.INTE = 1;       // Enable external interrupt
    INTCONbits.GIE = 1;        // Global interrupt enable
}

void vdelay(int n)
{
    int i;
    for (i=0;i<=n;i++)
    {
     __delay_us(100);
    }
}

void scan_eyes(int n, int m, uint8_t led1, uint8_t led2) // PWM sweep high f to low f
{
 int i,j,k;
 int i1,i2,i3,pw1,pw2;
 uint8_t sGPIO;

 i1=1; i2=-1; pw1=0; pw2=n;
 sGPIO = GPIO;
 for (k=0;k<m;k++)
 {
  for (j=0;j<n;j++)
   {
    for (i=0;i<n;i++)
     {
      if (i>pw1)
       {
        sGPIO = sGPIO & ~led1;
       }
      else
       {
        sGPIO = sGPIO | led1;
       }
      if (i>pw2)
       {
        sGPIO = sGPIO & ~led2;
       }
      else
       {
        sGPIO = sGPIO | led2;
       }
      GPIO = sGPIO;
     }
    pw1 = pw1 + i1;
    pw2 = pw2 + i2;
   }
  i3 = i1; i1 = i2, i2 = i3;
 }
}

void main()
{
    uint8_t r, d=200, rp=3;

    init();
    gi=0;
    GPIO = 0b00000000;
    while(1)
    {
     switch (gi)
      {
       case 0:
       GPIO = 0b00000001;
       break;

       case 1:
       GPIO = 0b00000010;
       break;

       case 2:
       GPIO = 0b00000011;
       break;

       case 3:
       GPIO = 0b00010000;
       break;

       case 4:
       GPIO = 0b00010001;
       break;

       case 5:
       GPIO = 0b00010010;
       break;

       case 6:
       GPIO = 0b00010011;
       break;

       case 7:
       GPIO = 0b00000000;
       break;

       default:
       scan_eyes(d,2,1,2);
      }
    }
}

void interrupt tc_int (void)
{
 if (INTCONbits.INTF==1)
  {
   INTCONbits.INTF = 0;
   gi=(gi+1)%9;
   vdelay(100);
  }
}