|
Forum Index : Microcontroller and PC projects : uM2(+): SETPINS - setting up many pins
| Author | Message | ||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
Herry's post prompted me to write a CFunction that I've been meaning to do for ages for my own use but should be generally useful. We often want to set multiple pins as inputs or outputs and end up with lists of "SETPIN" commands. The attached CFunction will set up any number of pins in a single command. The syntax should be obvious from the example code. The code supports DIN, DOUT and AIN and the options OC, PULLUP, PULLDOWN. The code is case insensitive and ignores spaces in the string. FIN, CIN and PIN could easily be added but they are normally just used for individual pins and adding them would just increase the size of the CFunction (source attached below). option explicit option default none setpins "DIN, PULLUP , 5 , 12, 8 ,10" ' set a number of pins as inputs with a pullup print pin(5),pin(12),pin(8),pin(10) setpins "DIN, PULLDOWN , 5 , 12, 8 ,10" ' set a number of pins as inputs with a pulldown print pin(5),pin(12),pin(8),pin(10) setpins "AIN, 23,24,25,26" 'set a number of pins as analogue inputs print pin(23),pin(24),pin(25),pin(26) setpins "DIN, 23,24,25,26" 'set them to digital inputs with no pullup or pulldown print pin(23),pin(24),pin(25),pin(26) setpins "DOUT, OC , 5 , 12, 8 ,10" 'set a number of pins as open collector outputs setpins "Dout, 23,24,25,26" 'set a number of pins as normal outputs setpins "off,23,24,25,26,5 , 12, 8 ,10" ' turn all pins off end CSub setpins 00000056 'MtoC 00801021 80870000 10E0000A 00802821 24830001 00873821 10600004 00000000 90660000 A0A60000 24A50001 1467FFFA 24630001 03E00008 A0A00000 'scmp 00001821 00831021 80420000 1440FFFD 24630001 00003021 00A61021 80420000 1440FFFD 24C60001 14660017 00000000 18600015 24020001 80A60000 80820000 00C23026 30C600DF 10C0000A 00001021 1000000D 00000000 80C70000 00823021 80C60000 00E63026 30C600DF 54C00006 00001021 24420001 1443FFF7 00A23021 03E00008 24020001 03E00008 00000000 'intconv 80830000 10600014 00001021 2465FFD0 30A500FF 2CA5000A 10A0000F 2402FFFF 10000005 00001021 30A500FF 2CA5000A 10A0000B 24840001 00022840 000210C0 00A21021 00431821 2462FFD0 80830001 1460FFF5 2465FFD0 03E00008 00000000 2402FFFF 03E00008 00000000 'getFPC 27BDFFF8 AFBF0004 00852023 03E42021 ACC40000 8FBF0004 03E00008 27BD0008 'main 27BDFFA0 AFBF005C AFBE0058 AFB70054 AFB60050 AFB5004C AFB40048 AFB30044 AFB20040 AFB1003C AFB00038 00808021 00002021 3C059D00 24A501A0 27A60010 0411FFE7 00000000 8FA20010 3C039D00 2463041C 00621821 AFA30020 8FA20010 3C039D00 24630424 00621821 AFA30028 8FA20010 3C039D00 24630428 00621821 AFA30030 8FA20010 3C039D00 2463042C 00621821 AFA30024 8FA20010 3C039D00 24630434 00621821 AFA3002C 8FA20010 3C039D00 24630440 00621821 AFA30034 3C029D00 8C420040 0040F809 240400FA 02002021 0411FF74 00000000 0040A821 0000B021 0000F021 0000A021 00008021 2412002C 24130020 24170001 02B08821 82220000 10520010 00002021 5040000F 27A20010 26030001 02A31821 10530004 27A60010 00C42821 A0A20004 24840001 26100001 80620000 10520003 00608821 1440FFF6 24630001 27A20010 00442021 A0800004 83A20014 5040004A 82220000 16800012 27A40014 8FA50020 0411FF5D 00000000 54400042 24160008 27A40014 8FA50028 0411FF57 00000000 5440003C 24160002 27A40014 8FA50030 0411FF51 00000000 10000036 02E2B00B 16970028 8FA50024 27A40014 0411FF4A 00000000 10400004 3AC30002 2402000E 1000002C 0043F00A 27A40014 8FA5002C 0411FF41 00000000 10400004 3AC30002 24020012 10000023 0043F00A 27A40014 8FA50034 0411FF38 00000000 10400004 3AC30008 24020009 1000001A 0043B00A 27A40014 0411FF54 00000000 2403FFFF 10430014 3C039D00 8C630010 00402021 02C02821 0060F809 03C03021 1000000E 82220000 0411FF48 00000000 2403FFFF 10430008 3C039D00 8C630010 00402021 02C02821 0060F809 03C03021 10000002 82220000 82220000 10400003 26100001 1000FF9B 26940001 8FBF005C 8FBE0058 8FB70054 8FB60050 8FB5004C 8FB40048 8FB30044 8FB20040 8FB1003C 8FB00038 03E00008 27BD0060 '.rodata '_dout 54554F44 00000000 '_din 004E4944 '_ain 004E4941 '_pullup 4C4C5550 00005055 '_pulldown 4C4C5550 4E574F44 00000000 '_OC 0000434F End CSub #define _SUPPRESS_PLIB_WARNING #include <stdarg.h> #include <xc.h> // Required for SFR defs #include <sys/attribs.h> // Required to use __longramfunc__ #include "../cfunctions.h" char *MtoC(char *p) { int k; char *p1, *p2; k = *p; p1 = p + 1; p2 = p; while(k) { if(p1) *p2++ = *p1; p1++; k--; } *p2 = 0; return p; } int scmp(char *p, char *q){ int k=0,j=0; while(p[k++]); while(q[j++]); if(k!=j){ return 0; } for(j=0;j<k;j++){ if((p[j]&0b11011111)!=(q[j]&0b11011111)){ return 0; } } return 1; } int intconv(char *p){ int n=0,k=0; while(p[k]){ if(p[k]>57 || p[k]<48){ return -1; } n*=10; n+=(p[k]-48); k++; } return n; } __attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c) { *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ; } void main(char *str){ volatile unsigned int libAddr ; getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor getFPCLab: { } static const char _dout[]="DOUT"; static const char _din[]="DIN"; static const char _ain[]="AIN"; static const char _pullup[]="PULLUP"; static const char _pulldown[]="PULLDOWN"; static const char _OC[]="OC"; char * dout = (unsigned char *)((void *)_dout + libAddr ); char * din = (unsigned char *)((void *)_din + libAddr ); char * ain = (unsigned char *)((void *)_ain + libAddr ); char * pullup = (unsigned char *)((void *)_pullup + libAddr ); char * pulldown = (unsigned char *)((void *)_pulldown + libAddr ); char * OC = (unsigned char *)((void *)_OC + libAddr ); char val[10]; int k,j=0,param=0, option=0; char *p=GetTempMemory(250); int mode=EXT_NOT_CONFIG,pin; p=MtoC(str); while(1){ k=0; while(p[j]!=',' && p[j]!=0) { if(p[j]!=32){ val[k]=p[j]; k++; } j++; } val[k]=0; if(val[0]){ if(param==0) { if(scmp(val,dout)){ mode=EXT_DIG_OUT; } else if(scmp(val,din)){ mode=EXT_DIG_IN; } else if(scmp(val,ain)){ mode=EXT_ANA_IN; } } else if (param==1){ if(scmp(val,pullup)){ if(mode==EXT_DIG_IN) option =CNPUSET; } else if(scmp(val,pulldown)){ if(mode==EXT_DIG_IN) option = CNPDSET; } else if(scmp(val,OC)){ if(mode==EXT_DIG_OUT) mode=EXT_OC_OUT; } else { pin=intconv(val); if(pin!=-1)ExtCfg(pin,mode,option); } } else { pin=intconv(val); if(pin!=-1)ExtCfg(pin,mode,option); } } if(p[j]==0)break; j++; param++; } } |
||||
Grogster![]() Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9750 |
I think matherp should change his username to 'Cfunction God'. The number of Cfunctions/Csubs he has written continues to astound me........... Smoke makes things work. When the smoke gets out, it stops! |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Newbe trying to get my head around Cfunctions and Csubs. I have got a problem with CFgen in that my copy downloaded from this forum does not give me the option to choose Csub or Cfunction is there a newer file out there that does? I have made some progress with MPLABX after reading the Cfuncions tutorials but have many questions. This one "setpins" works on my MX100, but if I compile the source myself with MPLABX the listing doesn't appear exactly as the one given plus when I use CFgen it produces a Cfunction which does not work. I also have an MX144 extreme, what settings would I have to change to run this on an Extreme apart from the Pin numbers being different? Trevor |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
CFunctions are "unsupported" on the MMX because of compiler changes in the latest releases of MPLabX. They can sometimes be got to work but there are too many "funnies" to make it possible to provide help. See top post in this thread this thread I always start with a known working project. Use the MPLabX project directory in the post referenced above and replace main.c Finally make sure you are using compiler version XC32 v1.33 - nothing else will work |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Thankyou Peter for your reply. does the same apply to Csubs? I was rather hoping to write my own driver for my displays which are CPLD type. I have got them working in a very limited way using basic but obviously I need to be able to speed up the routines dramatically and hook into the GUI if possible. Any ideas on CFgen the problem? Trevor |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Sorry! didn't read all post, have found the item on CFgen!!!! Trevor |
||||
redrok![]() Senior Member Joined: 15/09/2014 Location: United StatesPosts: 209 |
Hi matherp; Thank you! Thank you!! Thank you!!!!![]() I have been coding a Charlieplexing cathode driver for a NIXIE Clock. While I got it to work, the code is very ugly and a bit slow. Charlieplexing entails complex manipulations of an output register where individual bits are constantly switched from outputs to inputs. I was about to ask if there was a better way to do this. Then Bingo, you throw out the perfect solution!! I edited your sample program a bit as I'm using a 28 pin uMITE by changing the pins to be compatible. ( 12 is the console and 8 is a ground.) ' SetPinS_Test.bas ' http://www.thebackshed.com/forum/forum_posts.asp?TID=8484&PN=1 ' EXPLORER28 ' -------------O--\MX170/--O--------------- ' | reset| 1| 1 |30|AVcc | ' | AD P2 | 2| 2 27|29|gnd | ' | SPIO AD P3 | 3| 3 26|28|P26 AD PWM2A | ' | PWM1A AD P4 | 4| 4 25|27|P25 AD SPIC | ' | PWM1B AD P5 | 5| 5 24|26|P24 AD PWM2B | ' | PWM1C AD P6 | 6| 6 23|25|P23 AD | ' | AD P7 | 7| 7 22|24|P22 D 5V Com1RX| ' | gnd| 8| 8 21|23|P21 D 5V Com1TX| ' |Com2TX D P9 | 9| 9 20| | | ' |Com2RX D P10|10|10 19|21|gnd | ' | Con TX |11|11 18|20|P18 D 5V I2CD |I2CD PFC8563 RTC ' | Con RX |12|12 17|19|P17 D 5V I2CC |I2CC PFC8563 RTC ' | VCC|13|13 16|18|P16 D 5V | ' |SPII 5V D P14|14|14 15|17|P15 D 5V | ' | +5V|15| |16|+5V | ' -------------O-----------O--------------- SETUP: CPU 40 Option BAUDRATE 115200 Option AUTORUN ON Option DISPLAY 24,100 Option COLORCODE ON Option Explicit Option Default None SetPinS "DIN ,PULLUP ,5,14,7,10" ' set a number of pins as inputs with a pullup Print Pin(5),Pin(14),Pin(7),Pin(10), " set a number of pins as inputs with a pullup" SetPinS "DIN ,PULLDOWN,5,14,7,10" ' set a number of pins as inputs with a pulldown Print Pin(5),Pin(14),Pin(7),Pin(10), " set a number of pins as inputs with a pulldown" SetPinS "AIN ,23,24,25,26" ' set a number of pins as analogue inputs Print Str$(Pin(23),2,5);Str$(Pin(24),2,5);Str$(Pin(25),2,5);Str$(Pin(26),2,5);" set a number of pins as analogue inputs" SetPinS "DIN ,23,24,25,26" ' set them to digital inputs with no pullup or pulldown Print Pin(23),Pin(24),Pin(25),Pin(26)," set them to digital inputs with no pullup or pulldown" SetPinS "DOUT, OC,5,14,7,10" ' set a number of pins as open collector outputs SetPinS "DOUT,23,24,25,26" ' set a number of pins as normal outputs SetPinS "Off ,23,24,25,26,5,14,7,10" ' turn all pins off End CSub setpins 00000056 'MtoC 00801021 80870000 10E0000A 00802821 24830001 00873821 10600004 00000000 90660000 A0A60000 24A50001 1467FFFA 24630001 03E00008 A0A00000 'scmp 00001821 00831021 80420000 1440FFFD 24630001 00003021 00A61021 80420000 1440FFFD 24C60001 14660017 00000000 18600015 24020001 80A60000 80820000 00C23026 30C600DF 10C0000A 00001021 1000000D 00000000 80C70000 00823021 80C60000 00E63026 30C600DF 54C00006 00001021 24420001 1443FFF7 00A23021 03E00008 24020001 03E00008 00000000 'intconv 80830000 10600014 00001021 2465FFD0 30A500FF 2CA5000A 10A0000F 2402FFFF 10000005 00001021 30A500FF 2CA5000A 10A0000B 24840001 00022840 000210C0 00A21021 00431821 2462FFD0 80830001 1460FFF5 2465FFD0 03E00008 00000000 2402FFFF 03E00008 00000000 'getFPC 27BDFFF8 AFBF0004 00852023 03E42021 ACC40000 8FBF0004 03E00008 27BD0008 'main 27BDFFA0 AFBF005C AFBE0058 AFB70054 AFB60050 AFB5004C AFB40048 AFB30044 AFB20040 AFB1003C AFB00038 00808021 00002021 3C059D00 24A501A0 27A60010 0411FFE7 00000000 8FA20010 3C039D00 2463041C 00621821 AFA30020 8FA20010 3C039D00 24630424 00621821 AFA30028 8FA20010 3C039D00 24630428 00621821 AFA30030 8FA20010 3C039D00 2463042C 00621821 AFA30024 8FA20010 3C039D00 24630434 00621821 AFA3002C 8FA20010 3C039D00 24630440 00621821 AFA30034 3C029D00 8C420040 0040F809 240400FA 02002021 0411FF74 00000000 0040A821 0000B021 0000F021 0000A021 00008021 2412002C 24130020 24170001 02B08821 82220000 10520010 00002021 5040000F 27A20010 26030001 02A31821 10530004 27A60010 00C42821 A0A20004 24840001 26100001 80620000 10520003 00608821 1440FFF6 24630001 27A20010 00442021 A0800004 83A20014 5040004A 82220000 16800012 27A40014 8FA50020 0411FF5D 00000000 54400042 24160008 27A40014 8FA50028 0411FF57 00000000 5440003C 24160002 27A40014 8FA50030 0411FF51 00000000 10000036 02E2B00B 16970028 8FA50024 27A40014 0411FF4A 00000000 10400004 3AC30002 2402000E 1000002C 0043F00A 27A40014 8FA5002C 0411FF41 00000000 10400004 3AC30002 24020012 10000023 0043F00A 27A40014 8FA50034 0411FF38 00000000 10400004 3AC30008 24020009 1000001A 0043B00A 27A40014 0411FF54 00000000 2403FFFF 10430014 3C039D00 8C630010 00402021 02C02821 0060F809 03C03021 1000000E 82220000 0411FF48 00000000 2403FFFF 10430008 3C039D00 8C630010 00402021 02C02821 0060F809 03C03021 10000002 82220000 82220000 10400003 26100001 1000FF9B 26940001 8FBF005C 8FBE0058 8FB70054 8FB60050 8FB5004C 8FB40048 8FB30044 8FB20040 8FB1003C 8FB00038 03E00008 27BD0060 '.rodata '_dout 54554F44 00000000 '_din 004E4944 '_ain 004E4941 '_pullup 4C4C5550 00005055 '_pulldown 4C4C5550 4E574F44 00000000 '_OC 0000434F End CSub 'Setup the uMITE Prompt Sub MM.PROMPT:Print Chr$(27)+"[0;31m";"SetPinS_Test";Chr$(27)+"[1;32m";">";Chr$(27)+"[1;30m";:End Sub I haven't actualy tested your "SetPinS" CFunction with the Charlieplexing driver yet, probably tomorrow. But, it has to be much simplier than what I was doing. And much faster. Again, Thanks for the good work! redrok |
||||
redrok![]() Senior Member Joined: 15/09/2014 Location: United StatesPosts: 209 |
Hi matherp; Yes indeed, your instructions work correctly when driving a Charlieplexing array. It would be very nice if SetPinS "DOUT" could also include the values for the selected pins. This would eliminate Port instruction following the SetPinS instruction. Port is a bit cumbersome to use here as the selected pins must only be matched to output pins else there is an error. I'm proposing that an Optional "=" be added to SetPinS "DOUT instruction. The values are then matched to the selected numbers and no error can be produced. The "=" in this variant would follow the syntax of the Pin(n)=Val format. I suspect my multiple lines of code could be reduced to 1 line. This would greatly save space when I drive the 56 transistor B56 Charlieplexing array. 'Matherp's Instructions What do you think?'SetPinS "AIN ,2,3,4,5" 'SetPinS "DIN ,2,3,4,5" 'SetPinS "DIN ,PULLDOWN,2,3,4,5" 'SetPinS "DIN ,PULLUP ,2,3,4,5" 'SetPinS "DOUT ,2,3,4,5" 'SetPinS "DOUT ,2,3,4,5 = Val2,Val3,Val4,Val5" ' Proposed Variant Instruction 'SetPinS "DOUT,OC ,2,3,4,5" 'SetPinS "DOUT,OC ,2,3,4,5 = Val2,Val3,Val4,Val5" ' Proposed Variant Instruction 'SetPinS "Off ,2,3,4,5" Test: Do For T = 1 To 7 On T Gosub B601,B602,B603,B604,B605,B606,B60B Pause P If Inkey$<>""Then Input P Next T Loop ' The 6 Transistors in a CharliePlex B6Array B601:SetPinS"DOUT,2,3,4":Port(2,3)=1:SetPinS"Din,4":SetPinS"Dout,2,3":End Sub'LED 1 B602:SetPinS"DOUT,2,3,4":Port(2,3)=1:SetPinS"Din,3":SetPinS"Dout,2,4":End Sub'LED 2 B603:SetPinS"DOUT,2,3,4":Port(2,3)=2:SetPinS"Din,2":SetPinS"Dout,3,4":End Sub'LED 3 B604:SetPinS"DOUT,2,3,4":Port(2,3)=2:SetPinS"Din,4":SetPinS"Dout,2,3":End Sub'LED 4 B605:SetPinS"DOUT,2,3,4":Port(2,3)=4:SetPinS"Din,3":SetPinS"Dout,2,4":End Sub'LED 5 B606:SetPinS"DOUT,2,3,4":Port(2,3)=4:SetPinS"Din,2":SetPinS"Dout,3,4":End Sub'LED 6 B60B:SetPinS"DOUT,2,3,4":Port(2,3)=0:End Sub 'LEDs Off or Blank ' The 6 Transistors in a CharliePlex B6Array with Proposed Varient Instruction ' B601:SetPinS "DOUT,2,3,4=1,0,0":SetPinS"Din,4":End Sub'LED 1 ' B602:SetPinS "DOUT,2,3,4=1,0,0":SetPinS"Din,3":End Sub'LED 2 ' B603:SetPinS "DOUT,2,3,4=0,1,0":SetPinS"Din,2":End Sub'LED 3 ' B604:SetPinS "DOUT,2,3,4=0,1,0":SetPinS"Din,4":End Sub'LED 4 ' B605:SetPinS "DOUT,2,3,4=0,0,1":SetPinS"Din,3":End Sub'LED 5 ' B606:SetPinS "DOUT,2,3,4=0,0,1":SetPinS"Din,2":End Sub'LED 6 ' B60B:SetPinS "DOUT,2,3,4=0,0,0":End Sub 'LEDs Off or Blank redrok |
||||
MicroBlocks![]() Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Would something like this work? [code] do CharliePlexPin 2, 4 CharliePlexPin 2, 3 CharliePlexPin 3, 2 CharliePlexPin 3, 4 CharliePlexPin 4, 3 CharliePlexPin 4, 2 CharliePlexPin 0, 0 loop SUB CharliePlexPin(PinON, PinIn) For P = 2 to 4 SETPIN P, DOUT PIN(P) = (P = PinOn) next if PinIn > 0 then SETPIN PinIN, DIN END SUB [/code] And if you make the subroutine function and variable names shorter: [code] do CP 2, 4: CP 2, 3: CP 3, 2: CP 3, 4: CP 4, 3: CP 4, 2: CP 0, 0 loop SUB CP(O, I) For P = 2 to 4: SETPIN P, DOUT: PIN(P) = (P = O): next if I > 0 then SETPIN I, DIN END SUB [/code] Microblocks. Build with logic. |
||||
redrok![]() Senior Member Joined: 15/09/2014 Location: United StatesPosts: 209 |
Hi MicroBlocks;Very nice!!! This is why your a Programmer and I'm a Muddler. This works nicely for the 6 transistor, B6Array, Charlieplexer. However, it doesn't work for higher order arrays. I edited your code for a 12 transistor, B12Array. Which always selects 2 outputs instead of only 1. Charlieplexing rules: 1. One pin must be an Output and HI 2. Another pin must be an Output and LOW 3. All other pins must be Inputs. 4. Blanking Exception, All Pins must be Outputs and either HI or LOW. I choose LOW. I can't get my head around what is going on in your code to make it follow the rules. I suspect both output pins are HI. PAUZ=1000 I think I did it correctly.Test12: do CP12 23,25 CP12 23,24 CP12 23,26 CP12 24,26 CP12 24,25 CP12 24,23 CP12 25,23 CP12 25,26 CP12 25,24 CP12 26,24 CP12 26,23 CP12 26,25 CP12 0, 0 loop SUB CP12(O, I) For P = 23 to 26 SETPIN P, DOUT PIN(P) = (P = O) Next If I > 0 then SETPIN I, DIN Pause PAUZ:If Inkey$<>""Then Input PAUZ END SUB Can you see the error? Or is something else needed? Thanks! redrok |
||||
MicroBlocks![]() Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
[quote]Charlieplexing rules: 1. One pin must be an Output and HI 2. Another pin must be an Output and LOW 3. All other pins must be Inputs. 4. Blanking Exception, All Pins must be Outputs and either HI or LOW. I choose LOW. [/quote] You will need to check both values and set them as output. The previous one had only one input. [code] SUB CP12(O1, O2) For P = 23 to 26 if P = O1 or P = O2 or (O1 = 0 and O2 = 0) then SETPIN P, DOUT PIN(P) = (P = O1) Else SETPIN P, DIN EndIf Next Pause PAUZ:If Inkey$<>""Then Input PAUZ END SUB [/code] Microblocks. Build with logic. |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |